Merge "[bc25] Do not make the scrim opaque when Dual Shade is open." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 96d6f32..5e9af6a 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -405,6 +405,12 @@
aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
}
+cc_aconfig_library {
+ name: "android.companion.virtualdevice.flags-aconfig-cc-host",
+ aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
+ host_supported: true,
+}
+
java_aconfig_library {
name: "android.companion.virtualdevice.flags-aconfig-java",
aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
diff --git a/Ravenwood.bp b/Ravenwood.bp
index 159c17e..87f1124 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -38,8 +38,8 @@
"--out-impl-jar $(location ravenwood.jar) " +
- "--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
- "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
+ "--gen-keep-all-file $(location hoststubgen_framework-minus-apex_keep_all.txt) " +
+ "--gen-input-dump-file $(location hoststubgen_framework-minus-apex_dump.txt) " +
"--in-jar $(location :framework-minus-apex-for-hoststubgen) " +
"--policy-override-file $(location :ravenwood-framework-policies) " +
@@ -54,14 +54,14 @@
"ravenwood.jar",
// Following files are created just as FYI.
- "hoststubgen_keep_all.txt",
- "hoststubgen_dump.txt",
+ "hoststubgen_framework-minus-apex_keep_all.txt",
+ "hoststubgen_framework-minus-apex_dump.txt",
"hoststubgen_framework-minus-apex.log",
"hoststubgen_framework-minus-apex_stats.csv",
"hoststubgen_framework-minus-apex_apis.csv",
],
- visibility: ["//visibility:private"],
+ defaults: ["ravenwood-internal-only-visibility-genrule"],
}
// Extract the impl jar from "framework-minus-apex.ravenwood-base" for subsequent build rules.
@@ -79,43 +79,6 @@
],
}
-// Extract the stats file.
-genrule {
- name: "framework-minus-apex.ravenwood.stats",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
- cmd: "cp $(in) $(out)",
- srcs: [
- ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_stats.csv}",
- ],
- out: [
- "hoststubgen_framework-minus-apex_stats.csv",
- ],
-}
-
-genrule {
- name: "framework-minus-apex.ravenwood.apis",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
- cmd: "cp $(in) $(out)",
- srcs: [
- ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_apis.csv}",
- ],
- out: [
- "hoststubgen_framework-minus-apex_apis.csv",
- ],
-}
-
-genrule {
- name: "framework-minus-apex.ravenwood.keep_all",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
- cmd: "cp $(in) $(out)",
- srcs: [
- ":framework-minus-apex.ravenwood-base{hoststubgen_keep_all.txt}",
- ],
- out: [
- "hoststubgen_framework-minus-apex_keep_all.txt",
- ],
-}
-
java_library {
name: "services.core-for-hoststubgen",
installable: false, // host only jar.
@@ -138,8 +101,8 @@
"--out-impl-jar $(location ravenwood.jar) " +
- "--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
- "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
+ "--gen-keep-all-file $(location hoststubgen_services.core_keep_all.txt) " +
+ "--gen-input-dump-file $(location hoststubgen_services.core_dump.txt) " +
"--in-jar $(location :services.core-for-hoststubgen) " +
"--policy-override-file $(location :ravenwood-services-policies) " +
@@ -154,14 +117,14 @@
"ravenwood.jar",
// Following files are created just as FYI.
- "hoststubgen_keep_all.txt",
- "hoststubgen_dump.txt",
+ "hoststubgen_services.core_keep_all.txt",
+ "hoststubgen_services.core_dump.txt",
"hoststubgen_services.core.log",
"hoststubgen_services.core_stats.csv",
"hoststubgen_services.core_apis.csv",
],
- visibility: ["//visibility:private"],
+ defaults: ["ravenwood-internal-only-visibility-genrule"],
}
java_genrule {
@@ -176,43 +139,6 @@
],
}
-// Extract the stats file.
-genrule {
- name: "services.core.ravenwood.stats",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
- cmd: "cp $(in) $(out)",
- srcs: [
- ":services.core.ravenwood-base{hoststubgen_services.core_stats.csv}",
- ],
- out: [
- "hoststubgen_services.core_stats.csv",
- ],
-}
-
-genrule {
- name: "services.core.ravenwood.apis",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
- cmd: "cp $(in) $(out)",
- srcs: [
- ":services.core.ravenwood-base{hoststubgen_services.core_apis.csv}",
- ],
- out: [
- "hoststubgen_services.core_apis.csv",
- ],
-}
-
-genrule {
- name: "services.core.ravenwood.keep_all",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
- cmd: "cp $(in) $(out)",
- srcs: [
- ":services.core.ravenwood-base{hoststubgen_keep_all.txt}",
- ],
- out: [
- "hoststubgen_services.core_keep_all.txt",
- ],
-}
-
java_library {
name: "services.core.ravenwood-jarjar",
defaults: ["ravenwood-internal-only-visibility-java"],
@@ -225,12 +151,15 @@
// Jars in "ravenwood-runtime" are set to the classpath, sorted alphabetically.
// Rename some of the dependencies to make sure they're included in the intended order.
-java_genrule {
+// Also apply jarjar.
+java_library {
name: "100-framework-minus-apex.ravenwood",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
- cmd: "cp $(in) $(out)",
- srcs: [":framework-minus-apex.ravenwood"],
- out: ["100-framework-minus-apex.ravenwood.jar"],
+ defaults: ["ravenwood-internal-only-visibility-java"],
+ static_libs: [
+ "framework-minus-apex.ravenwood",
+ ],
+ sdk_version: "core_platform",
+ jarjar_rules: ":ravenwood-framework-jarjar-rules",
}
java_genrule {
diff --git a/WEAR_OWNERS b/WEAR_OWNERS
index 4ffb239..52c07e0 100644
--- a/WEAR_OWNERS
+++ b/WEAR_OWNERS
@@ -12,3 +12,4 @@
shijianli@google.com
latkin@google.com
djsollen@google.com
+hdhabu@google.com
\ No newline at end of file
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 762e2af..0750c8d 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -145,7 +145,9 @@
Intent.ACTION_USER_STARTED,
Intent.ACTION_MEDIA_MOUNTED,
Intent.ACTION_USER_UNLOCKED,
- Intent.ACTION_USER_STOPPED);
+ Intent.ACTION_USER_STOPPED,
+ Intent.ACTION_PROFILE_AVAILABLE,
+ Intent.ACTION_PROFILE_UNAVAILABLE);
mUserSwitchWaiter = new UserSwitchWaiter(TAG, TIMEOUT_IN_SECOND);
removeAnyPreviousTestUsers();
if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) {
@@ -1230,6 +1232,255 @@
}
}
+ /** Tests creating a private profile. */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void createPrivateProfile() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ Log.i(TAG, "Starting timer");
+
+ final int userId = createPrivateProfileUser();
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests creating and starting a newly created private profile. This test waits for the
+ * {@link Intent.ACTION_USER_STARTED} to be received.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void createAndStartPrivateProfile_realistic() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ Log.i(TAG, "Starting timer");
+ final int userId = createPrivateProfileUser();
+
+ // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
+ // ACTION_USER_STARTED.
+ runThenWaitForBroadcasts(userId, () -> {
+ mIam.startUserInBackground(userId);
+ }, Intent.ACTION_USER_STARTED);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /** Tests for stopping the private profile. */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileStopped() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ runThenWaitForBroadcasts(userId, () -> {
+ startUserInBackgroundAndWaitForUnlock(userId);
+ }, Intent.ACTION_MEDIA_MOUNTED);
+
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ stopUser(userId);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests unlocking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileUnlock() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+ waitCoolDownPeriod();
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests unlocking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api and waiting for the
+ * {@link Intent.ACTION_PROFILE_AVAILABLE} to be received.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileUnlock_realistic() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+ waitCoolDownPeriod();
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ runThenWaitForBroadcasts(userId, () -> {
+ mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
+ }, Intent.ACTION_PROFILE_AVAILABLE);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests locking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileLock() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests locking a newly-created private profile using the
+ * {@link UserManager#requestQuietModeEnabled} api and waiting for the
+ * {@link Intent.ACTION_PROFILE_UNAVAILABLE} to be received.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileLock_realistic() throws RemoteException {
+
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ runThenWaitForBroadcasts(userId, () -> {
+ mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+ }, Intent.ACTION_PROFILE_UNAVAILABLE);
+
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /** Tests removing a newly-created private profile */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileRemove() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+ removeUser(userId);
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /** Tests installing a pre-existing app in a private profile. */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileInstall() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests creating a new private profile, starting it, installing an app, and launching that app
+ * in it.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileCreateStartInstallAndLaunchApp() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ final int userId = createPrivateProfileUser();
+ startUserInBackgroundAndWaitForUnlock(userId);
+ installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+ startApp(userId, DUMMY_PACKAGE_NAME);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
+ /**
+ * Tests starting & launching an already-installed app in a private profile.
+ */
+ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+ public void privateProfileStartAndLaunchApp() throws RemoteException {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createPrivateProfileUser();
+ WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
+ installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+ mRunner.resumeTiming();
+ Log.i(TAG, "Starting timer");
+
+ startUserInBackgroundAndWaitForUnlock(userId);
+ startApp(userId, DUMMY_PACKAGE_NAME);
+
+ mRunner.pauseTiming();
+ Log.i(TAG, "Stopping timer");
+ removeUser(userId);
+ waitCoolDownPeriod();
+ mRunner.resumeTimingForNextIteration();
+ }
+ }
+
/** Creates a new user, returning its userId. */
private int createUserNoFlags() {
return createUserWithFlags(/* flags= */ 0);
@@ -1252,6 +1503,18 @@
return userInfo.id;
}
+ /** Creates a private profile under the current user, returning its userId. */
+ private int createPrivateProfileUser() {
+ final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME,
+ UserManager.USER_TYPE_PROFILE_PRIVATE, /* flags */ 0, mAm.getCurrentUser());
+ attestFalse(
+ "Creating a private profile failed. Most likely there is already a pre-existing "
+ + "private profile on the device.",
+ userInfo == null);
+ mUsersToRemove.add(userInfo.id);
+ return userInfo.id;
+ }
+
/**
* Start user in background and wait for it to unlock by waiting for
* UserState.mUnlockProgress.finish().
diff --git a/api/coverage/tools/ExtractFlaggedApis.kt b/api/coverage/tools/ExtractFlaggedApis.kt
index 5efda98..bf67187 100644
--- a/api/coverage/tools/ExtractFlaggedApis.kt
+++ b/api/coverage/tools/ExtractFlaggedApis.kt
@@ -75,10 +75,10 @@
fun getClassFlag(classItem: ClassItem): String? {
var classFlag = getFlagAnnotation(classItem)
var cur = classItem
- // If a class is not an inner class, use its @FlaggedApi annotation value.
+ // If a class is not a nested class, use its @FlaggedApi annotation value.
// Otherwise, use the flag value of the closest outer class that is annotated by @FlaggedApi.
- while (cur.isInnerClass() && classFlag == null) {
- cur = cur.parent() as ClassItem
+ while (classFlag == null) {
+ cur = cur.containingClass() ?: break
classFlag = getFlagAnnotation(cur)
}
return classFlag
diff --git a/api/gen_combined_removed_dex.sh b/api/gen_combined_removed_dex.sh
index e0153f7..2860e2e 100755
--- a/api/gen_combined_removed_dex.sh
+++ b/api/gen_combined_removed_dex.sh
@@ -6,6 +6,6 @@
# Convert each removed.txt to the "dex format" equivalent, and print all output.
for f in "$@"; do
- "$metalava_path" signature-to-dex "$f" "${tmp_dir}/tmp"
+ "$metalava_path" signature-to-dex "$f" --out "${tmp_dir}/tmp"
cat "${tmp_dir}/tmp"
done
diff --git a/core/api/current.txt b/core/api/current.txt
index 69ead8f..5456c15 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -11336,7 +11336,7 @@
field public static final String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
field public static final String CATEGORY_VOICE = "android.intent.category.VOICE";
field public static final String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
- field @FlaggedApi("android.service.chooser.chooser_album_text") public static final int CHOOSER_CONTENT_TYPE_ALBUM = 1; // 0x1
+ field public static final int CHOOSER_CONTENT_TYPE_ALBUM = 1; // 0x1
field @NonNull public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR;
field public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
field public static final String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
@@ -11359,7 +11359,7 @@
field public static final String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
field public static final String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
field @FlaggedApi("android.service.chooser.chooser_payload_toggling") public static final String EXTRA_CHOOSER_ADDITIONAL_CONTENT_URI = "android.intent.extra.CHOOSER_ADDITIONAL_CONTENT_URI";
- field @FlaggedApi("android.service.chooser.chooser_album_text") public static final String EXTRA_CHOOSER_CONTENT_TYPE_HINT = "android.intent.extra.CHOOSER_CONTENT_TYPE_HINT";
+ field public static final String EXTRA_CHOOSER_CONTENT_TYPE_HINT = "android.intent.extra.CHOOSER_CONTENT_TYPE_HINT";
field public static final String EXTRA_CHOOSER_CUSTOM_ACTIONS = "android.intent.extra.CHOOSER_CUSTOM_ACTIONS";
field @FlaggedApi("android.service.chooser.chooser_payload_toggling") public static final String EXTRA_CHOOSER_FOCUSED_ITEM_POSITION = "android.intent.extra.CHOOSER_FOCUSED_ITEM_POSITION";
field public static final String EXTRA_CHOOSER_MODIFY_SHARE_ACTION = "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION";
@@ -43901,6 +43901,7 @@
field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT = "satellite_connection_hysteresis_sec_int";
field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT = "satellite_entitlement_status_refresh_days_int";
field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL = "satellite_entitlement_supported_bool";
+ field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ESOS_SUPPORTED_BOOL = "satellite_esos_supported_bool";
field public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = "show_4g_for_3g_data_icon_bool";
field public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL = "show_4g_for_lte_data_icon_bool";
field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 0ab2588..e4a8407 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -318,6 +318,14 @@
}
+package android.net.wifi {
+
+ public final class WifiMigration {
+ method @FlaggedApi("android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration") public static void migrateLegacyKeystoreToWifiBlobstore();
+ }
+
+}
+
package android.nfc {
public class NfcServiceManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1d40c53..abc2224 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3447,6 +3447,7 @@
}
public static interface VirtualDeviceManager.ActivityListener {
+ method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public default void onActivityLaunchBlocked(int, @NonNull android.content.ComponentName, int);
method public void onDisplayEmpty(int);
method @Deprecated public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
method public default void onTopActivityChanged(int, @NonNull android.content.ComponentName, int);
@@ -3476,6 +3477,7 @@
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.input.VirtualMouseConfig);
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualNavigationTouchpad createVirtualNavigationTouchpad(@NonNull android.hardware.input.VirtualNavigationTouchpadConfig);
+ method @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualRotaryEncoder createVirtualRotaryEncoder(@NonNull android.hardware.input.VirtualRotaryEncoderConfig);
method @FlaggedApi("android.companion.virtual.flags.virtual_stylus") @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualStylus createVirtualStylus(@NonNull android.hardware.input.VirtualStylusConfig);
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.input.VirtualTouchscreenConfig);
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
@@ -3522,6 +3524,7 @@
field @Deprecated public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1
field @FlaggedApi("android.companion.virtual.flags.dynamic_policy") public static final int POLICY_TYPE_ACTIVITY = 3; // 0x3
field public static final int POLICY_TYPE_AUDIO = 1; // 0x1
+ field @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public static final int POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR = 6; // 0x6
field @FlaggedApi("android.companion.virtual.flags.virtual_camera") public static final int POLICY_TYPE_CAMERA = 5; // 0x5
field @FlaggedApi("android.companion.virtual.flags.cross_device_clipboard") public static final int POLICY_TYPE_CLIPBOARD = 4; // 0x4
field public static final int POLICY_TYPE_RECENTS = 2; // 0x2
@@ -3772,6 +3775,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public android.content.Intent registerReceiverForAllUsers(@Nullable android.content.BroadcastReceiver, @NonNull android.content.IntentFilter, @Nullable String, @Nullable android.os.Handler, int);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, @Nullable android.os.Bundle);
method public void sendBroadcastMultiplePermissions(@NonNull android.content.Intent, @NonNull String[], @Nullable android.app.BroadcastOptions);
+ method @FlaggedApi("android.os.ordered_broadcast_multiple_permissions") public void sendOrderedBroadcastMultiplePermissions(@NonNull android.content.Intent, @NonNull String[], @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
field public static final String AMBIENT_CONTEXT_SERVICE = "ambient_context";
@@ -5762,6 +5766,37 @@
method @NonNull public android.hardware.input.VirtualNavigationTouchpadConfig build();
}
+ @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") public class VirtualRotaryEncoder implements java.io.Closeable {
+ method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
+ method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendScrollEvent(@NonNull android.hardware.input.VirtualRotaryEncoderScrollEvent);
+ }
+
+ @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") public final class VirtualRotaryEncoderConfig extends android.hardware.input.VirtualInputDeviceConfig implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualRotaryEncoderConfig> CREATOR;
+ }
+
+ public static final class VirtualRotaryEncoderConfig.Builder extends android.hardware.input.VirtualInputDeviceConfig.Builder<android.hardware.input.VirtualRotaryEncoderConfig.Builder> {
+ ctor public VirtualRotaryEncoderConfig.Builder();
+ method @NonNull public android.hardware.input.VirtualRotaryEncoderConfig build();
+ }
+
+ @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") public final class VirtualRotaryEncoderScrollEvent implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getEventTimeNanos();
+ method @FloatRange(from=-1.0F, to=1.0f) public float getScrollAmount();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualRotaryEncoderScrollEvent> CREATOR;
+ }
+
+ public static final class VirtualRotaryEncoderScrollEvent.Builder {
+ ctor public VirtualRotaryEncoderScrollEvent.Builder();
+ method @NonNull public android.hardware.input.VirtualRotaryEncoderScrollEvent build();
+ method @NonNull public android.hardware.input.VirtualRotaryEncoderScrollEvent.Builder setEventTimeNanos(long);
+ method @NonNull public android.hardware.input.VirtualRotaryEncoderScrollEvent.Builder setScrollAmount(@FloatRange(from=-1.0F, to=1.0f) float);
+ }
+
@FlaggedApi("android.companion.virtual.flags.virtual_stylus") public class VirtualStylus implements java.io.Closeable {
method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendButtonEvent(@NonNull android.hardware.input.VirtualStylusButtonEvent);
@@ -11367,8 +11402,9 @@
method public long getNumPacketsTx();
method public long getRxTimeMillis();
method public long getSleepTimeMillis();
- method @NonNull public long getTimeInRatMicros(int);
- method @NonNull public long getTimeInRxSignalStrengthLevelMicros(@IntRange(from=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_GREAT) int);
+ method public long getTimeInRatMicros(int);
+ method public long getTimeInRxSignalStrengthLevelMicros(@IntRange(from=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_GREAT) int);
+ method @FlaggedApi("com.android.server.power.optimization.streamlined_connectivity_battery_stats") public long getTxTimeMillis(@IntRange(from=android.telephony.ModemActivityInfo.TX_POWER_LEVEL_0, to=android.telephony.ModemActivityInfo.TX_POWER_LEVEL_4) int);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.os.connectivity.CellularBatteryStats> CREATOR;
}
@@ -12907,7 +12943,6 @@
field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_OTHER = 0; // 0x0
field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_PROMOTION = 1; // 0x1
field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_SOCIAL_MEDIA = 2; // 0x2
- field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_UNKNOWN = -1; // 0xffffffff
}
public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 1352465..b7de93a 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2608,6 +2608,18 @@
}
+package android.os.connectivity {
+
+ public final class CellularBatteryStats implements android.os.Parcelable {
+ ctor @FlaggedApi("com.android.server.power.optimization.streamlined_connectivity_battery_stats") public CellularBatteryStats(long, long, long, long, long, long, long, long, long, long, @NonNull long[], @NonNull long[], @NonNull long[], long);
+ }
+
+ public final class WifiBatteryStats implements android.os.Parcelable {
+ ctor @FlaggedApi("com.android.server.power.optimization.streamlined_connectivity_battery_stats") public WifiBatteryStats(long, long, long, long, long, long, long, long, long, long, long, long, long, @NonNull long[], @NonNull long[], @NonNull long[], long);
+ }
+
+}
+
package android.os.health {
public class HealthKeys {
diff --git a/core/java/Android.bp b/core/java/Android.bp
index fae411d..128fb62 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -20,10 +20,43 @@
"**/*.java",
"**/*.aidl",
":framework-nfc-non-updatable-sources",
+ ":messagequeue-gen",
+ ],
+ // Exactly one of the below will be added to srcs by messagequeue-gen
+ exclude_srcs: [
+ "android/os/LegacyMessageQueue/MessageQueue.java",
+ "android/os/ConcurrentMessageQueue/MessageQueue.java",
+ "android/os/SemiConcurrentMessageQueue/MessageQueue.java",
],
visibility: ["//frameworks/base"],
}
+// Add selected MessageQueue.java implementation to srcs
+soong_config_module_type {
+ name: "release_package_messagequeue_implementation_srcs",
+ module_type: "genrule",
+ config_namespace: "messagequeue",
+ value_variables: ["release_package_messagequeue_implementation"],
+ properties: [
+ "srcs",
+ ],
+}
+
+// Output the selected android/os/MessageQueue.java implementation
+release_package_messagequeue_implementation_srcs {
+ name: "messagequeue-gen",
+ soong_config_variables: {
+ release_package_messagequeue_implementation: {
+ srcs: ["android/os/%s"],
+ conditions_default: {
+ srcs: ["android/os/LegacyMessageQueue/MessageQueue.java"],
+ },
+ },
+ },
+ cmd: "mkdir -p android/os/; cp $(in) $(out);",
+ out: ["android/os/MessageQueue.java"],
+}
+
aidl_library {
name: "IDropBoxManagerService_aidl",
srcs: [
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 2313fa2..5214d2c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2981,9 +2981,7 @@
new AppOpInfo.Builder(OP_ESTABLISH_VPN_MANAGER, OPSTR_ESTABLISH_VPN_MANAGER,
"ESTABLISH_VPN_MANAGER").setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
new AppOpInfo.Builder(OP_ACCESS_RESTRICTED_SETTINGS, OPSTR_ACCESS_RESTRICTED_SETTINGS,
- "ACCESS_RESTRICTED_SETTINGS").setDefaultMode(
- android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
- ? MODE_DEFAULT : MODE_ALLOWED)
+ "ACCESS_RESTRICTED_SETTINGS").setDefaultMode(AppOpsManager.MODE_ALLOWED)
.setDisableReset(true).setRestrictRead(true).build(),
new AppOpInfo.Builder(OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO,
"RECEIVE_SOUNDTRIGGER_AUDIO").setDefaultMode(AppOpsManager.MODE_ALLOWED)
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index baed4fd..7e2a580 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1552,6 +1552,17 @@
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ String[] receiverPermissions = receiverPermission == null ? null
+ : new String[] {receiverPermission};
+ sendOrderedBroadcastAsUserMultiplePermissions(intent, user, receiverPermissions, appOp,
+ options, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+
+ @Override
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ String[] receiverPermissions, int appOp, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
IIntentReceiver rd = null;
if (resultReceiver != null) {
if (mPackageInfo != null) {
@@ -1571,8 +1582,6 @@
}
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
- String[] receiverPermissions = receiverPermission == null ? null
- : new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntentWithFeature(
@@ -1599,6 +1608,20 @@
}
@Override
+ public void sendOrderedBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
+ String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
+ int initialCode, String initialData, @Nullable Bundle initialExtras,
+ @Nullable Bundle options) {
+ int intAppOp = AppOpsManager.OP_NONE;
+ if (!TextUtils.isEmpty(receiverAppOp)) {
+ intAppOp = AppOpsManager.strOpToOp(receiverAppOp);
+ }
+ sendOrderedBroadcastAsUserMultiplePermissions(intent, getUser(), receiverPermissions,
+ intAppOp, options, resultReceiver, scheduler, initialCode, initialData,
+ initialExtras);
+ }
+
+ @Override
public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission,
String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
String initialData, @Nullable Bundle initialExtras, Bundle options) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 15b13dc..ffb920b 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -757,6 +757,15 @@
void addStartInfoTimestamp(int key, long timestampNs, int userId);
/**
+ * Reports view related timestamps to be added to the calling apps most
+ * recent {@link ApplicationStartInfo}.
+ *
+ * @param renderThreadDrawStartTimeNs Clock monotonic time in nanoseconds of RenderThread draw start
+ * @param framePresentedTimeNs Clock monotonic time in nanoseconds of frame presented
+ */
+ oneway void reportStartInfoViewTimestamps(long renderThreadDrawStartTimeNs, long framePresentedTimeNs);
+
+ /**
* Return a list of {@link ApplicationExitInfo} records.
*
* <p class="note"> Note: System stores these historical information in a ring buffer, older
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index bd80dc1..69b5222 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -499,32 +499,31 @@
/**
* Activity Action: Launch an Automatic Zen Rule configuration screen
- * <p>
- * Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
+ *
+ * <p> Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
* existing rule should be displayed. If the rule id is missing or null, apps should display
* a configuration screen where users can create a new instance of the rule.
- * <p>
- * Output: Nothing
- * <p>
- * You can have multiple activities handling this intent, if you support multiple
- * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
- * rule types so that users can create new instances or configure existing ones, you need
- * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
- * to your activity tag in your manifest. If you'd like to limit the number of rules a user
- * can create from this flow, you can additionally optionally include
- * {@link #META_DATA_RULE_INSTANCE_LIMIT}.
*
- * For example,
- * <meta-data
- * android:name="android.app.zen.automatic.ruleType"
- * android:value="@string/my_condition_rule">
- * </meta-data>
- * <meta-data
- * android:name="android.app.zen.automatic.ruleInstanceLimit"
- * android:value="1">
- * </meta-data>
- * </p>
- * </p>
+ * <p> Output: Nothing
+ *
+ * <p> You can have multiple activities handling this intent, if you support multiple
+ * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
+ * rule types so that users can create new instances or configure existing ones, you need
+ * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
+ * to your activity tag in your manifest. If you'd like to limit the number of rules a user
+ * can create from this flow, you can additionally optionally include
+ * {@link #META_DATA_RULE_INSTANCE_LIMIT}. For example,
+ *
+ * <pre>
+ * {@code
+ * <meta-data
+ * android:name="android.service.zen.automatic.ruleType"
+ * android:value="@string/my_condition_rule" />
+ * <meta-data
+ * android:name="android.service.zen.automatic.ruleInstanceLimit"
+ * android:value="1" />
+ * }
+ * </pre>
*
* @see #addAutomaticZenRule(AutomaticZenRule)
*/
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index bb7f893..fd4d8e9 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -30,6 +30,7 @@
import android.content.res.CompatResources;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.content.res.Flags;
import android.content.res.Resources;
import android.content.res.ResourcesImpl;
import android.content.res.ResourcesKey;
@@ -73,7 +74,7 @@
static final String TAG = "ResourcesManager";
private static final boolean DEBUG = false;
- private static ResourcesManager sResourcesManager;
+ private static volatile ResourcesManager sResourcesManager;
/**
* Internal lock object
@@ -138,16 +139,22 @@
private final ArrayMap<String, SharedLibraryAssets> mSharedLibAssetsMap =
new ArrayMap<>();
+ @VisibleForTesting
+ public ArrayMap<String, SharedLibraryAssets> getRegisteredResourcePaths() {
+ return mSharedLibAssetsMap;
+ }
+
/**
* The internal function to register the resources paths of a package (e.g. a shared library).
* This will collect the package resources' paths from its ApplicationInfo and add them to all
* existing and future contexts while the application is running.
*/
public void registerResourcePaths(@NonNull String uniqueId, @NonNull ApplicationInfo appInfo) {
- SharedLibraryAssets sharedLibAssets = new SharedLibraryAssets(appInfo.sourceDir,
- appInfo.splitSourceDirs, appInfo.sharedLibraryFiles,
- appInfo.resourceDirs, appInfo.overlayPaths);
+ if (!Flags.registerResourcePaths()) {
+ return;
+ }
+ final var sharedLibAssets = new SharedLibraryAssets(appInfo);
synchronized (mLock) {
if (mSharedLibAssetsMap.containsKey(uniqueId)) {
Slog.v(TAG, "Package resources' paths for uniqueId: " + uniqueId
@@ -155,18 +162,37 @@
return;
}
mSharedLibAssetsMap.put(uniqueId, sharedLibAssets);
- appendLibAssetsLocked(sharedLibAssets.getAllAssetPaths());
- Slog.v(TAG, "The following resources' paths have been added: "
- + Arrays.toString(sharedLibAssets.getAllAssetPaths()));
+ appendLibAssetsLocked(sharedLibAssets);
+ Slog.v(TAG, "The following library key has been added: "
+ + sharedLibAssets.getResourcesKey());
}
}
- private static class ApkKey {
+ /**
+ * Apply the registered library paths to the passed impl object
+ * @return the hash code for the current version of the registered paths
+ */
+ public int updateResourceImplWithRegisteredLibs(@NonNull ResourcesImpl impl) {
+ if (!Flags.registerResourcePaths()) {
+ return 0;
+ }
+
+ final var collector = new PathCollector(null);
+ final int size = mSharedLibAssetsMap.size();
+ for (int i = 0; i < size; i++) {
+ final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey();
+ collector.appendKey(libraryKey);
+ }
+ impl.getAssets().addPresetApkKeys(extractApkKeys(collector.collectedKey()));
+ return size;
+ }
+
+ public static class ApkKey {
public final String path;
public final boolean sharedLib;
public final boolean overlay;
- ApkKey(String path, boolean sharedLib, boolean overlay) {
+ public ApkKey(String path, boolean sharedLib, boolean overlay) {
this.path = path;
this.sharedLib = sharedLib;
this.overlay = overlay;
@@ -190,6 +216,12 @@
return this.path.equals(other.path) && this.sharedLib == other.sharedLib
&& this.overlay == other.overlay;
}
+
+ @Override
+ public String toString() {
+ return "ApkKey[" + (sharedLib ? "lib" : "app") + (overlay ? ", overlay" : "") + ": "
+ + path + "]";
+ }
}
/**
@@ -327,17 +359,20 @@
sResourcesManager = resourcesManager;
return oldResourceManager;
}
-
}
@UnsupportedAppUsage
public static ResourcesManager getInstance() {
- synchronized (ResourcesManager.class) {
- if (sResourcesManager == null) {
- sResourcesManager = new ResourcesManager();
+ var rm = sResourcesManager;
+ if (rm == null) {
+ synchronized (ResourcesManager.class) {
+ rm = sResourcesManager;
+ if (rm == null) {
+ sResourcesManager = rm = new ResourcesManager();
+ }
}
- return sResourcesManager;
}
+ return rm;
}
/**
@@ -505,7 +540,10 @@
return "/data/resource-cache/" + path.substring(1).replace('/', '@') + "@idmap";
}
- private @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException {
+ /**
+ * Loads the ApkAssets object for the passed key, or picks the one from the cache if available.
+ */
+ public @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException {
ApkAssets apkAssets;
// Optimistically check if this ApkAssets exists somewhere else.
@@ -747,8 +785,8 @@
private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked(
@NonNull ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) {
ResourcesImpl impl = findResourcesImplForKeyLocked(key);
- // ResourcesImpl also need to be recreated if its shared library count is not up-to-date.
- if (impl == null || impl.getSharedLibCount() != mSharedLibAssetsMap.size()) {
+ // ResourcesImpl also need to be recreated if its shared library hash is not up-to-date.
+ if (impl == null || impl.getAppliedSharedLibsHash() != mSharedLibAssetsMap.size()) {
impl = createResourcesImpl(key, apkSupplier);
if (impl != null) {
mResourceImpls.put(key, new WeakReference<>(impl));
@@ -1533,54 +1571,107 @@
}
}
- private void appendLibAssetsLocked(String[] libAssets) {
- synchronized (mLock) {
- // Record which ResourcesImpl need updating
- // (and what ResourcesKey they should update to).
- final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
+ /**
+ * A utility class to collect resources paths into a ResourcesKey object:
+ * - Separates the libraries and the overlays into different sets as those are loaded in
+ * different ways.
+ * - Allows to start with an existing original key object, and copies all non-path related
+ * properties into the final one.
+ * - Preserves the path order while dropping all duplicates in an efficient manner.
+ */
+ private static class PathCollector {
+ public final ResourcesKey originalKey;
+ public final ArrayList<String> orderedLibs = new ArrayList<>();
+ public final ArraySet<String> libsSet = new ArraySet<>();
+ public final ArrayList<String> orderedOverlays = new ArrayList<>();
+ public final ArraySet<String> overlaysSet = new ArraySet<>();
- final int implCount = mResourceImpls.size();
- for (int i = 0; i < implCount; i++) {
- final ResourcesKey key = mResourceImpls.keyAt(i);
- final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
- final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
- if (impl == null) {
- Slog.w(TAG, "Found a ResourcesImpl which is null, skip it and continue to "
- + "append shared library assets for next ResourcesImpl.");
- continue;
- }
+ static void appendNewPath(@NonNull String path,
+ @NonNull ArraySet<String> uniquePaths, @NonNull ArrayList<String> orderedPaths) {
+ if (uniquePaths.add(path)) {
+ orderedPaths.add(path);
+ }
+ }
- var newDirs = new ArrayList<String>();
- var dirsSet = new ArraySet<String>();
- if (key.mLibDirs != null) {
- final int dirsLength = key.mLibDirs.length;
- for (int k = 0; k < dirsLength; k++) {
- newDirs.add(key.mLibDirs[k]);
- dirsSet.add(key.mLibDirs[k]);
- }
- }
- final int assetsLength = libAssets.length;
- for (int j = 0; j < assetsLength; j++) {
- if (dirsSet.add(libAssets[j])) {
- newDirs.add(libAssets[j]);
- }
- }
- String[] newLibAssets = newDirs.toArray(new String[0]);
- if (!Arrays.equals(newLibAssets, key.mLibDirs)) {
- updatedResourceKeys.put(impl, new ResourcesKey(
- key.mResDir,
- key.mSplitResDirs,
- key.mOverlayPaths,
- newLibAssets,
- key.mDisplayId,
- key.mOverrideConfiguration,
- key.mCompatInfo,
- key.mLoaders));
- }
+ static void appendAllNewPaths(@Nullable String[] paths,
+ @NonNull ArraySet<String> uniquePaths, @NonNull ArrayList<String> orderedPaths) {
+ if (paths == null) return;
+ for (int i = 0, size = paths.length; i < size; i++) {
+ appendNewPath(paths[i], uniquePaths, orderedPaths);
+ }
+ }
+
+ PathCollector(@Nullable ResourcesKey original) {
+ originalKey = original;
+ if (originalKey != null) {
+ appendKey(originalKey);
+ }
+ }
+
+ public void appendKey(@NonNull ResourcesKey key) {
+ appendAllNewPaths(key.mLibDirs, libsSet, orderedLibs);
+ appendAllNewPaths(key.mOverlayPaths, overlaysSet, orderedOverlays);
+ }
+
+ boolean isSameAsOriginal() {
+ if (originalKey == null) {
+ return orderedLibs.isEmpty() && orderedOverlays.isEmpty();
+ }
+ return ((originalKey.mLibDirs == null && orderedLibs.isEmpty())
+ || (originalKey.mLibDirs != null
+ && originalKey.mLibDirs.length == orderedLibs.size()))
+ && ((originalKey.mOverlayPaths == null && orderedOverlays.isEmpty())
+ || (originalKey.mOverlayPaths != null
+ && originalKey.mOverlayPaths.length == orderedOverlays.size()));
+ }
+
+ @NonNull ResourcesKey collectedKey() {
+ return new ResourcesKey(
+ originalKey == null ? null : originalKey.mResDir,
+ originalKey == null ? null : originalKey.mSplitResDirs,
+ orderedOverlays.toArray(new String[0]), orderedLibs.toArray(new String[0]),
+ originalKey == null ? 0 : originalKey.mDisplayId,
+ originalKey == null ? null : originalKey.mOverrideConfiguration,
+ originalKey == null ? null : originalKey.mCompatInfo,
+ originalKey == null ? null : originalKey.mLoaders);
+ }
+ }
+
+ /**
+ * Takes the original resources key and the one containing a set of library paths and overlays
+ * to append, and combines them together. In case when the original key already contains all
+ * those paths this function returns null, otherwise it makes a new ResourcesKey object.
+ */
+ private @Nullable ResourcesKey createNewResourceKeyIfNeeded(
+ @NonNull ResourcesKey original, @NonNull ResourcesKey library) {
+ final var collector = new PathCollector(original);
+ collector.appendKey(library);
+ return collector.isSameAsOriginal() ? null : collector.collectedKey();
+ }
+
+ /**
+ * Append the newly registered shared library asset paths to all existing resources objects.
+ */
+ private void appendLibAssetsLocked(@NonNull SharedLibraryAssets libAssets) {
+ // Record the ResourcesImpl's that need updating, and what ResourcesKey they should
+ // update to.
+ final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
+ final int implCount = mResourceImpls.size();
+ for (int i = 0; i < implCount; i++) {
+ final ResourcesKey key = mResourceImpls.keyAt(i);
+ final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
+ final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
+ if (impl == null) {
+ Slog.w(TAG, "Found a null ResourcesImpl, skipped.");
+ continue;
}
- redirectAllResourcesToNewImplLocked(updatedResourceKeys);
+ final var newKey = createNewResourceKeyIfNeeded(key, libAssets.getResourcesKey());
+ if (newKey != null) {
+ updatedResourceKeys.put(impl, newKey);
+ }
}
+ redirectAllResourcesToNewImplLocked(updatedResourceKeys);
}
private void applyNewResourceDirsLocked(@Nullable final String[] oldSourceDirs,
@@ -1718,8 +1809,9 @@
}
}
- // Another redirect function which will loop through all Resources and reload ResourcesImpl
- // if it needs a shared library asset paths update.
+ // Another redirect function which will loop through all Resources in the process, even the ones
+ // the app created outside of the regular Android Runtime, and reload their ResourcesImpl if it
+ // needs a shared library asset paths update.
private void redirectAllResourcesToNewImplLocked(
@NonNull final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys) {
cleanupReferences(mAllResourceReferences, mAllResourceReferencesQueue);
@@ -1835,52 +1927,35 @@
}
}
- public static class SharedLibraryAssets{
- private final String[] mAssetPaths;
+ @VisibleForTesting
+ public static class SharedLibraryAssets {
+ private final ResourcesKey mResourcesKey;
- SharedLibraryAssets(String sourceDir, String[] splitSourceDirs, String[] sharedLibraryFiles,
- String[] resourceDirs, String[] overlayPaths) {
- mAssetPaths = collectAssetPaths(sourceDir, splitSourceDirs, sharedLibraryFiles,
- resourceDirs, overlayPaths);
- }
-
- private @NonNull String[] collectAssetPaths(String sourceDir, String[] splitSourceDirs,
- String[] sharedLibraryFiles, String[] resourceDirs, String[] overlayPaths) {
- final String[][] inputLists = {
- splitSourceDirs, sharedLibraryFiles, resourceDirs, overlayPaths
- };
-
- final ArraySet<String> assetPathSet = new ArraySet<>();
- final List<String> assetPathList = new ArrayList<>();
- if (sourceDir != null) {
- assetPathSet.add(sourceDir);
- assetPathList.add(sourceDir);
- }
-
- for (int i = 0; i < inputLists.length; i++) {
- if (inputLists[i] != null) {
- for (int j = 0; j < inputLists[i].length; j++) {
- if (assetPathSet.add(inputLists[i][j])) {
- assetPathList.add(inputLists[i][j]);
- }
- }
- }
- }
- return assetPathList.toArray(new String[0]);
+ private SharedLibraryAssets(ApplicationInfo appInfo) {
+ // We're loading all library's files as shared libs, regardless where they are in
+ // its own ApplicationInfo.
+ final var collector = new PathCollector(null);
+ PathCollector.appendNewPath(appInfo.sourceDir, collector.libsSet,
+ collector.orderedLibs);
+ PathCollector.appendAllNewPaths(appInfo.splitSourceDirs, collector.libsSet,
+ collector.orderedLibs);
+ PathCollector.appendAllNewPaths(appInfo.sharedLibraryFiles, collector.libsSet,
+ collector.orderedLibs);
+ PathCollector.appendAllNewPaths(appInfo.resourceDirs, collector.overlaysSet,
+ collector.orderedOverlays);
+ PathCollector.appendAllNewPaths(appInfo.overlayPaths, collector.overlaysSet,
+ collector.orderedOverlays);
+ mResourcesKey = collector.collectedKey();
}
/**
- * @return all the asset paths of this collected in this class.
+ * @return the resources key for this library assets.
*/
- public @NonNull String[] getAllAssetPaths() {
- return mAssetPaths;
+ public @NonNull ResourcesKey getResourcesKey() {
+ return mResourcesKey;
}
}
- public @NonNull ArrayMap<String, SharedLibraryAssets> getSharedLibAssetsMap() {
- return new ArrayMap<>(mSharedLibAssetsMap);
- }
-
/**
* Add all resources references to the list which is designed to help to append shared library
* asset paths. This is invoked in Resources constructor to include all Resources instances.
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 348d4d8f..a249c39 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1647,10 +1647,13 @@
// Calling out without a lock held.
mUiAutomationConnection.executeShellCommand(command, sink, null);
- } catch (IOException ioe) {
- Log.e(LOG_TAG, "Error executing shell command!", ioe);
- } catch (RemoteException re) {
- Log.e(LOG_TAG, "Error executing shell command!", re);
+ } catch (IOException | RemoteException e) {
+ Log.e(LOG_TAG, "Error executing shell command!", e);
+ } catch (IllegalArgumentException | NullPointerException | SecurityException e) {
+ // An exception of these types is propagated from the server.
+ // Rethrow it to keep the old behavior. To avoid FD leak, close the source.
+ IoUtils.closeQuietly(source);
+ throw e;
} finally {
IoUtils.closeQuietly(sink);
}
@@ -1734,10 +1737,15 @@
// Calling out without a lock held.
mUiAutomationConnection.executeShellCommandWithStderr(
command, sink_read, source_write, stderr_sink_read);
- } catch (IOException ioe) {
- Log.e(LOG_TAG, "Error executing shell command!", ioe);
- } catch (RemoteException re) {
- Log.e(LOG_TAG, "Error executing shell command!", re);
+ } catch (IOException | RemoteException e) {
+ Log.e(LOG_TAG, "Error executing shell command!", e);
+ } catch (IllegalArgumentException | SecurityException | NullPointerException e) {
+ // An exception of these types is propagated from the server.
+ // Rethrow it to keep the old behavior. To avoid FD leaks, close the sources.
+ IoUtils.closeQuietly(sink_write);
+ IoUtils.closeQuietly(source_read);
+ IoUtils.closeQuietly(stderr_source_read);
+ throw e;
} finally {
IoUtils.closeQuietly(sink_read);
IoUtils.closeQuietly(source_write);
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 3c4bd9e..5e21e05 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -550,8 +550,21 @@
try {
process = Runtime.getRuntime().exec(command);
- } catch (IOException exc) {
- throw new RuntimeException("Error running shell command '" + command + "'", exc);
+ } catch (IOException ex) {
+ // Make sure the passed FDs are closed.
+ IoUtils.closeQuietly(sink);
+ IoUtils.closeQuietly(source);
+ IoUtils.closeQuietly(stderrSink);
+ // No to need to wrap in RuntimeException. Only to keep the old behavior.
+ // This is just logged and not propagated to the remote caller anyway.
+ throw new RuntimeException("Error running shell command '" + command + "'", ex);
+ } catch (IllegalArgumentException | NullPointerException | SecurityException ex) {
+ // Make sure the passed FDs are closed.
+ IoUtils.closeQuietly(sink);
+ IoUtils.closeQuietly(source);
+ IoUtils.closeQuietly(stderrSink);
+ // Rethrow the exception. This will be propagated to the remote caller.
+ throw ex;
}
// Read from process and write to pipe
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 257aff0..1a72df1 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -262,13 +262,6 @@
public static final String COMMAND_GOING_TO_SLEEP = "android.wallpaper.goingtosleep";
/**
- * Command for {@link #sendWallpaperCommand}: reported when a physical display switch event
- * happens, e.g. fold and unfold.
- * @hide
- */
- public static final String COMMAND_DISPLAY_SWITCH = "android.wallpaper.displayswitch";
-
- /**
* Command for {@link #sendWallpaperCommand}: reported when the wallpaper that was already
* set is re-applied by the user.
* @hide
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index 24f18cc..0653839 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -17,7 +17,9 @@
package android.companion.virtual;
import android.app.PendingIntent;
+import android.companion.virtual.IVirtualDeviceActivityListener;
import android.companion.virtual.IVirtualDeviceIntentInterceptor;
+import android.companion.virtual.IVirtualDeviceSoundEffectListener;
import android.companion.virtual.audio.IAudioConfigChangedCallback;
import android.companion.virtual.audio.IAudioRoutingCallback;
import android.companion.virtual.sensor.VirtualSensor;
@@ -35,6 +37,8 @@
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
+import android.hardware.input.VirtualRotaryEncoderConfig;
+import android.hardware.input.VirtualRotaryEncoderScrollEvent;
import android.hardware.input.VirtualStylusButtonEvent;
import android.hardware.input.VirtualStylusConfig;
import android.hardware.input.VirtualStylusMotionEvent;
@@ -158,6 +162,12 @@
void createVirtualStylus(in VirtualStylusConfig config, IBinder token);
/**
+ * Creates a new rotary encoder and registers it with the input framework with the given token.
+ */
+ @EnforcePermission("CREATE_VIRTUAL_DEVICE")
+ void createVirtualRotaryEncoder(in VirtualRotaryEncoderConfig config, IBinder token);
+
+ /**
* Removes the input device corresponding to the given token from the framework.
*/
@EnforcePermission("CREATE_VIRTUAL_DEVICE")
@@ -218,6 +228,12 @@
boolean sendStylusButtonEvent(IBinder token, in VirtualStylusButtonEvent event);
/**
+ * Injects a scroll event from the virtual rotary encoder corresponding to the given token.
+ */
+ @EnforcePermission("CREATE_VIRTUAL_DEVICE")
+ boolean sendRotaryEncoderScrollEvent(IBinder token, in VirtualRotaryEncoderScrollEvent event);
+
+ /**
* Returns all virtual sensors created for this device.
*/
@EnforcePermission("CREATE_VIRTUAL_DEVICE")
@@ -282,4 +298,15 @@
*/
@EnforcePermission("CREATE_VIRTUAL_DEVICE")
String getVirtualCameraId(in VirtualCameraConfig camera);
+
+ /**
+ * Setter for listeners that live in the client process, namely in
+ * {@link android.companion.virtual.VirtualDeviceInternal}.
+ *
+ * This is needed for virtual devices that are created by the system, as the VirtualDeviceImpl
+ * object is created before the returned VirtualDeviceInternal one.
+ */
+ @EnforcePermission("CREATE_VIRTUAL_DEVICE")
+ void setListeners(in IVirtualDeviceActivityListener activityListener,
+ in IVirtualDeviceSoundEffectListener soundEffectListener);
}
diff --git a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
index fc7f85c..39371a3 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
@@ -32,7 +32,7 @@
* @param topActivity The component name of the top activity.
* @param userId The user ID associated with the top activity.
*/
- void onTopActivityChanged(int displayId, in ComponentName topActivity, in int userId);
+ void onTopActivityChanged(int displayId, in ComponentName topActivity, int userId);
/**
* Called when the display becomes empty (e.g. if the user hits back on the last
@@ -41,4 +41,13 @@
* @param displayId The display ID that became empty.
*/
void onDisplayEmpty(int displayId);
+
+ /**
+ * Called when an activity launch was blocked due to a policy violation.
+ *
+ * @param displayId The display ID on which the activity tried to launch.
+ * @param componentName The component name of the blocked activity.
+ * @param userId The user ID associated with the blocked activity.
+ */
+ void onActivityLaunchBlocked(int displayId, in ComponentName componentName, int userId);
}
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index 60448ba..d3fcfc6 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -46,6 +46,8 @@
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualNavigationTouchpad;
import android.hardware.input.VirtualNavigationTouchpadConfig;
+import android.hardware.input.VirtualRotaryEncoder;
+import android.hardware.input.VirtualRotaryEncoderConfig;
import android.hardware.input.VirtualStylus;
import android.hardware.input.VirtualStylusConfig;
import android.hardware.input.VirtualTouchscreen;
@@ -126,6 +128,22 @@
Binder.restoreCallingIdentity(token);
}
}
+
+ @Override
+ public void onActivityLaunchBlocked(int displayId, ComponentName componentName,
+ @UserIdInt int userId) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mActivityListenersLock) {
+ for (int i = 0; i < mActivityListeners.size(); i++) {
+ mActivityListeners.valueAt(i)
+ .onActivityLaunchBlocked(displayId, componentName, userId);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
};
private final IVirtualDeviceSoundEffectListener mSoundEffectListener =
new IVirtualDeviceSoundEffectListener.Stub() {
@@ -162,6 +180,20 @@
mSoundEffectListener);
}
+ VirtualDeviceInternal(
+ IVirtualDeviceManager service,
+ Context context,
+ IVirtualDevice virtualDevice) {
+ mService = service;
+ mContext = context.getApplicationContext();
+ mVirtualDevice = virtualDevice;
+ try {
+ mVirtualDevice.setListeners(mActivityListenerBinder, mSoundEffectListener);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
int getDeviceId() {
try {
return mVirtualDevice.getDeviceId();
@@ -335,6 +367,19 @@
}
}
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ @NonNull
+ VirtualRotaryEncoder createVirtualRotaryEncoder(@NonNull VirtualRotaryEncoderConfig config) {
+ try {
+ final IBinder token = new Binder(
+ "android.hardware.input.VirtualRotaryEncoder:" + config.getInputDeviceName());
+ mVirtualDevice.createVirtualRotaryEncoder(config, token);
+ return new VirtualRotaryEncoder(config, mVirtualDevice, token);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
@NonNull
VirtualNavigationTouchpad createVirtualNavigationTouchpad(
@NonNull VirtualNavigationTouchpadConfig config) {
@@ -496,6 +541,12 @@
public void onDisplayEmpty(int displayId) {
mExecutor.execute(() -> mActivityListener.onDisplayEmpty(displayId));
}
+
+ public void onActivityLaunchBlocked(int displayId, ComponentName componentName,
+ @UserIdInt int userId) {
+ mExecutor.execute(() ->
+ mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId));
+ }
}
/**
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index ed55a3f..296ca33 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -56,6 +56,8 @@
import android.hardware.input.VirtualMouseConfig;
import android.hardware.input.VirtualNavigationTouchpad;
import android.hardware.input.VirtualNavigationTouchpadConfig;
+import android.hardware.input.VirtualRotaryEncoder;
+import android.hardware.input.VirtualRotaryEncoderConfig;
import android.hardware.input.VirtualStylus;
import android.hardware.input.VirtualStylusConfig;
import android.hardware.input.VirtualTouchscreen;
@@ -573,6 +575,12 @@
new VirtualDeviceInternal(service, context, associationId, params);
}
+ /** @hide */
+ public VirtualDevice(IVirtualDeviceManager service, Context context,
+ IVirtualDevice virtualDevice) {
+ mVirtualDeviceInternal = new VirtualDeviceInternal(service, context, virtualDevice);
+ }
+
/**
* Returns the unique ID of this virtual device.
*/
@@ -947,6 +955,23 @@
}
/**
+ * Creates a virtual rotary encoder.
+ *
+ * @param config the configuration for the virtual rotary encoder.
+ * @see android.view.InputDevice#SOURCE_ROTARY_ENCODER
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ @NonNull
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_ROTARY)
+ public VirtualRotaryEncoder createVirtualRotaryEncoder(
+ @NonNull VirtualRotaryEncoderConfig config) {
+ if (!android.companion.virtualdevice.flags.Flags.virtualRotary()) {
+ throw new UnsupportedOperationException("Virtual rotary support not enabled");
+ }
+ return mVirtualDeviceInternal.createVirtualRotaryEncoder(config);
+ }
+
+ /**
* Creates a VirtualAudioDevice, capable of recording audio emanating from this device,
* or injecting audio from another device.
*
@@ -1101,7 +1126,7 @@
}
/**
- * Listener for activity changes in this virtual device.
+ * Listener for activity changes and other activity events on a virtual device.
*
* @hide
*/
@@ -1142,6 +1167,20 @@
* @param displayId The display ID that became empty.
*/
void onDisplayEmpty(int displayId);
+
+ /**
+ * Called when an activity launch was blocked due to a policy violation.
+ *
+ * @param displayId The display ID on which the activity tried to launch.
+ * @param componentName The component name of the blocked activity.
+ * @param userId The user ID associated with the blocked activity.
+ *
+ * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
+ * @see VirtualDevice#addActivityPolicyExemption(ComponentName)
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
+ default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName,
+ @UserIdInt int userId) {}
}
/**
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index f9a9da1..f7f842f 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -171,7 +171,7 @@
* @hide
*/
@IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY,
- POLICY_TYPE_CLIPBOARD})
+ POLICY_TYPE_CLIPBOARD, POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR})
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
public @interface DynamicPolicyType {}
@@ -263,6 +263,22 @@
@FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA)
public static final int POLICY_TYPE_CAMERA = 5;
+ /**
+ * Tells the virtual device framework how to handle activity launches that were blocked due to
+ * the current activity policy.
+ *
+ * <ul>
+ * <li>{@link #DEVICE_POLICY_DEFAULT}: Show UI informing the user of the blocked activity
+ * launch on the virtual display that the activity was originally launched on.
+ * <li>{@link #DEVICE_POLICY_CUSTOM}: Does not inform the user of the blocked activity
+ * launch. The virtual device owner can use this policy together with
+ * {@link VirtualDeviceManager.ActivityListener#onActivityLaunchBlocked} to provide custom
+ * experience on the virtual device.
+ * </ul>
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
+ public static final int POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR = 6;
+
private final int mLockState;
@NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
@NavigationPolicy
@@ -1174,6 +1190,10 @@
mDevicePolicies.delete(POLICY_TYPE_CAMERA);
}
+ if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ mDevicePolicies.delete(POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR);
+ }
+
if ((mAudioPlaybackSessionId != AUDIO_SESSION_ID_GENERATE
|| mAudioRecordingSessionId != AUDIO_SESSION_ID_GENERATE)
&& mDevicePolicies.get(POLICY_TYPE_AUDIO, DEVICE_POLICY_DEFAULT)
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 1e781532..64d2081 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -41,12 +41,27 @@
flag {
namespace: "virtual_devices"
+ name: "activity_control_api"
+ description: "Enable APIs for fine grained activity policy, fallback and callbacks"
+ bug: "333443509"
+}
+
+flag {
+ namespace: "virtual_devices"
name: "camera_device_awareness"
description: "Enable device awareness in camera service"
bug: "305170199"
}
flag {
+ name: "virtual_rotary"
+ is_exported: true
+ namespace: "virtual_devices"
+ description: "Enable virtual rotary input"
+ bug: "320328752"
+}
+
+flag {
namespace: "virtual_devices"
name: "device_aware_drm"
description: "Makes MediaDrm APIs device-aware"
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 24fd000..ab58f43 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2916,6 +2916,21 @@
@Nullable String initialData, @Nullable Bundle initialExtras);
/**
+ * Similar to above but takes array of names of permissions that a receiver must hold in order
+ * to receive your broadcast. If empty, no permissions are required.
+ *
+ * @see #sendOrderedBroadcastAsUser(Intent, UserHandle, String,
+ * BroadcastReceiver, Handler, int, String, Bundle)
+ * @hide
+ */
+ @SuppressWarnings("HiddenAbstractMethod")
+ @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
+ public abstract void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent,
+ UserHandle user, String[] receiverPermissions, int appOp, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras);
+
+ /**
* Version of
* {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
* Bundle)} that allows you to specify the App Op to enforce restrictions on which receivers
@@ -2997,6 +3012,21 @@
}
/**
+ * Like {@link #sendOrderedBroadcast(Intent, String, String, BroadcastReceiver, Handler, int,
+ * String, Bundle)}, but also allows specification of a list of multiple permissions.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_ORDERED_BROADCAST_MULTIPLE_PERMISSIONS)
+ @SystemApi
+ public void sendOrderedBroadcastMultiplePermissions(
+ @NonNull Intent intent, @NonNull String[] receiverPermissions,
+ @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
+ @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+ @Nullable Bundle initialExtras, @Nullable Bundle options) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
* Intent you are sending stays around after the broadcast is complete,
* so that others can quickly retrieve that data through the return
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index a475c29..79fa6ea 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -652,6 +652,16 @@
resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
+ /** @hide */
+ @Override
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ @Nullable String[] receiverPermission, int appOp, @Nullable Bundle options,
+ @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
+ int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
+ mBase.sendOrderedBroadcastAsUserMultiplePermissions(intent, user, receiverPermission, appOp,
+ options, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+
@Override
public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent,
@Nullable String receiverPermission, @Nullable String receiverAppOp,
@@ -661,6 +671,17 @@
scheduler, initialCode, initialData, initialExtras);
}
+ /** @hide */
+ @Override
+ public void sendOrderedBroadcastMultiplePermissions(
+ @NonNull Intent intent, @NonNull String[] receiverPermissions,
+ @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
+ @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+ @Nullable Bundle initialExtras, @Nullable Bundle options) {
+ mBase.sendOrderedBroadcastMultiplePermissions(intent, receiverPermissions, receiverAppOp,
+ resultReceiver, scheduler, initialCode, initialData, initialExtras, options);
+ }
+
@Override
public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, int initialCode,
@Nullable String receiverPermission, @Nullable String receiverAppOp,
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a6edab1..112507e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6068,7 +6068,6 @@
* @see #CHOOSER_CONTENT_TYPE_ALBUM
* @see #createChooser(Intent, CharSequence)
*/
- @FlaggedApi(android.service.chooser.Flags.FLAG_CHOOSER_ALBUM_TEXT)
public static final String EXTRA_CHOOSER_CONTENT_TYPE_HINT =
"android.intent.extra.CHOOSER_CONTENT_TYPE_HINT";
@@ -6085,7 +6084,6 @@
*
* @see #EXTRA_CHOOSER_CONTENT_TYPE_HINT
*/
- @FlaggedApi(android.service.chooser.Flags.FLAG_CHOOSER_ALBUM_TEXT)
public static final int CHOOSER_CONTENT_TYPE_ALBUM = 1;
/**
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 4f06209..57ffed4 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1331,6 +1331,7 @@
* This change id is the gatekeeper for all treatments that force a given min aspect ratio.
* Enabling this change will allow the following min aspect ratio treatments to be applied:
* <ul>
+ * <li>OVERRIDE_MIN_ASPECT_RATIO_SMALL
* <li>OVERRIDE_MIN_ASPECT_RATIO_MEDIUM
* <li>OVERRIDE_MIN_ASPECT_RATIO_LARGE
* </ul>
@@ -1372,6 +1373,22 @@
public static final long OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY = 203647190L; // buganizer id
/**
+ * This change id sets the activity's min aspect ratio to a small value as defined by
+ * OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE.
+ *
+ * This treatment only takes effect if OVERRIDE_MIN_ASPECT_RATIO is also enabled.
+ * @hide
+ */
+ @ChangeId
+ @Overridable
+ @Disabled
+ // TODO(b/349060719): Add CTS tests.
+ public static final long OVERRIDE_MIN_ASPECT_RATIO_SMALL = 349045028L; // buganizer id
+
+ /** @hide Small override aspect ratio, currently 4:3. */
+ public static final float OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE = 4 / 3f;
+
+ /**
* This change id sets the activity's min aspect ratio to a medium value as defined by
* OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE.
*
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index a9c07d1..124d07f 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -126,7 +126,7 @@
description: "Talkback focus doesn't move to the 'If you change your Google Account picture…' after swiping next to move the focus from 'Choose a picture'"
bug: "330835921"
metadata {
- purpose: PURPOSE_BUGFIX
+ purpose: PURPOSE_BUGFIX
}
}
@@ -136,7 +136,7 @@
description: "Talkback doesn't announce 'selected' after double tapping the button in the picture list in 'Choose a picture' page."
bug: "330840549"
metadata {
- purpose: PURPOSE_BUGFIX
+ purpose: PURPOSE_BUGFIX
}
}
@@ -146,7 +146,27 @@
description: "Fix potential unexpected behavior due to concurrent file writing"
bug: "339351031"
metadata {
- purpose: PURPOSE_BUGFIX
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "cache_quiet_mode_state"
+ namespace: "multiuser"
+ description: "Optimise quiet mode state retrieval"
+ bug: "350420769"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "cache_user_serial_number"
+ namespace: "multiuser"
+ description: "Optimise user serial number retrieval"
+ bug: "340018451"
+ metadata {
+ purpose: PURPOSE_BUGFIX
}
}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index c0c1c31..899c2d6 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -17,6 +17,7 @@
package android.content.res;
import static android.content.res.Resources.ID_NULL;
+import static android.app.ResourcesManager.ApkKey;
import android.annotation.AnyRes;
import android.annotation.ArrayRes;
@@ -26,6 +27,7 @@
import android.annotation.StringRes;
import android.annotation.StyleRes;
import android.annotation.TestApi;
+import android.app.ResourcesManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration.NativeConfig;
@@ -265,7 +267,7 @@
}
sSystemApkAssetsSet = new ArraySet<>(apkAssets);
- sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]);
+ sSystemApkAssets = apkAssets.toArray(new ApkAssets[0]);
if (sSystem == null) {
sSystem = new AssetManager(true /*sentinel*/);
}
@@ -449,7 +451,7 @@
@Deprecated
@UnsupportedAppUsage
public int addAssetPath(String path) {
- return addAssetPathInternal(List.of(path), false, false, false);
+ return addAssetPathInternal(List.of(new ApkKey(path, false, false)), false);
}
/**
@@ -459,7 +461,7 @@
@Deprecated
@UnsupportedAppUsage
public int addAssetPathAsSharedLibrary(String path) {
- return addAssetPathInternal(List.of(path), false, true, false);
+ return addAssetPathInternal(List.of(new ApkKey(path, true, false)), false);
}
/**
@@ -469,27 +471,26 @@
@Deprecated
@UnsupportedAppUsage
public int addOverlayPath(String path) {
- return addAssetPathInternal(List.of(path), true, false, false);
+ return addAssetPathInternal(List.of(new ApkKey(path, false, true)), false);
}
/**
* @hide
*/
- public void addSharedLibraryPaths(@NonNull List<String> paths) {
- addAssetPathInternal(paths, false, true, true);
+ public void addPresetApkKeys(@NonNull List<ApkKey> keys) {
+ addAssetPathInternal(keys, true);
}
- private int addAssetPathInternal(List<String> paths, boolean overlay, boolean appAsLib,
- boolean presetAssets) {
- Objects.requireNonNull(paths, "paths");
- if (paths.isEmpty()) {
+ private int addAssetPathInternal(List<ApkKey> apkKeys, boolean presetAssets) {
+ Objects.requireNonNull(apkKeys, "apkKeys");
+ if (apkKeys.isEmpty()) {
return 0;
}
synchronized (this) {
ensureOpenLocked();
- // See if we already have some of the paths loaded.
+ // See if we already have some of the apkKeys loaded.
final int originalAssetsCount = mApkAssets.length;
// Getting an assets' path is a relatively expensive operation, cache them.
@@ -498,22 +499,22 @@
assetPaths.put(mApkAssets[i].getAssetPath(), i);
}
- final ArrayList<String> newPaths = new ArrayList<>(paths.size());
+ final var newKeys = new ArrayList<ApkKey>(apkKeys.size());
int lastFoundIndex = -1;
- for (int i = 0, pathsSize = paths.size(); i < pathsSize; i++) {
- final var path = paths.get(i);
- final int index = assetPaths.getOrDefault(path, -1);
- if (index < 0) {
- newPaths.add(path);
+ for (int i = 0, pathsSize = apkKeys.size(); i < pathsSize; i++) {
+ final var key = apkKeys.get(i);
+ final var index = assetPaths.get(key.path);
+ if (index == null) {
+ newKeys.add(key);
} else {
lastFoundIndex = index;
}
}
- if (newPaths.isEmpty()) {
+ if (newKeys.isEmpty()) {
return lastFoundIndex + 1;
}
- final var newAssets = loadAssets(newPaths, overlay, appAsLib);
+ final var newAssets = loadAssets(newKeys);
if (newAssets.isEmpty()) {
return 0;
}
@@ -557,28 +558,19 @@
return newAssetsArray;
}
- private static @NonNull ArrayList<ApkAssets> loadAssets(@NonNull ArrayList<String> paths,
- boolean overlay, boolean appAsLib) {
- final int pathsSize = paths.size();
+ private static @NonNull ArrayList<ApkAssets> loadAssets(@NonNull ArrayList<ApkKey> keys) {
+ final int pathsSize = keys.size();
final var loadedAssets = new ArrayList<ApkAssets>(pathsSize);
+ final var resourcesManager = ResourcesManager.getInstance();
for (int i = 0; i < pathsSize; i++) {
- final var path = paths.get(i);
+ final var key = keys.get(i);
try {
- final ApkAssets assets;
- if (overlay || path.endsWith(".frro")) {
- // TODO(b/70343104): This hardcoded path will be removed once
- // addAssetPathInternal is deleted.
- final String idmapPath = "/data/resource-cache/"
- + path.substring(1).replace('/', '@')
- + "@idmap";
- assets = ApkAssets.loadOverlayFromPath(idmapPath, 0 /* flags */);
- } else {
- assets = ApkAssets.loadFromPath(path,
- appAsLib ? ApkAssets.PROPERTY_DYNAMIC : 0);
- }
- loadedAssets.add(assets);
+ // ResourcesManager has a cache of loaded assets, ensuring we don't open the same
+ // file repeatedly, which is useful for the common overlays and registered
+ // shared libraries.
+ loadedAssets.add(resourcesManager.loadApkAssets(key));
} catch (IOException e) {
- Log.w(TAG, "Failed to load asset, path = " + path, e);
+ Log.w(TAG, "Failed to load asset, key = " + key, e);
}
}
return loadedAssets;
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 5031faa..7b18117 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -32,6 +32,9 @@
import android.util.SparseArray;
import android.util.StateSet;
import android.util.Xml;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
import com.android.internal.R;
import com.android.internal.graphics.ColorUtils;
@@ -44,7 +47,9 @@
import java.io.IOException;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
*
@@ -793,4 +798,61 @@
return new ColorStateList(stateSpecs, colors);
}
};
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream out) {
+ for (int[] states : mStateSpecs) {
+ long specToken = out.start(ColorStateListProto.STATE_SPECS);
+ for (int state : states) {
+ out.write(ColorStateListProto.StateSpec.STATE, state);
+ }
+ out.end(specToken);
+ }
+ for (int color : mColors) {
+ out.write(ColorStateListProto.COLORS, color);
+ }
+ }
+
+ /** @hide */
+ public static ColorStateList createFromProto(ProtoInputStream in)
+ throws Exception {
+ List<int[]> stateSpecs = new ArrayList<>();
+ List<Integer> colors = new ArrayList<>();
+
+
+ while (in.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ switch (in.getFieldNumber()) {
+ case (int) ColorStateListProto.COLORS:
+ colors.add(in.readInt(ColorStateListProto.COLORS));
+ break;
+ case (int) ColorStateListProto.STATE_SPECS:
+ final long stateToken = in.start(ColorStateListProto.STATE_SPECS);
+ List<Integer> states = new ArrayList<>();
+ while (in.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ switch (in.getFieldNumber()) {
+ case (int) ColorStateListProto.StateSpec.STATE:
+ states.add(in.readInt(ColorStateListProto.StateSpec.STATE));
+ break;
+ default:
+ Log.w(TAG, "Unhandled field while reading Icon proto!\n"
+ + ProtoUtils.currentFieldToString(in));
+ }
+ }
+ int[] statesArray = new int[states.size()];
+ Arrays.setAll(statesArray, states::get);
+ stateSpecs.add(statesArray);
+ in.end(stateToken);
+ break;
+ default:
+ Log.w(TAG, "Unhandled field while reading Icon proto!\n"
+ + ProtoUtils.currentFieldToString(in));
+ }
+ }
+
+ int[][] stateSpecsArray = new int[stateSpecs.size()][];
+ Arrays.setAll(stateSpecsArray, stateSpecs::get);
+ int[] colorsArray = new int[colors.size()];
+ Arrays.setAll(colorsArray, colors::get);
+ return new ColorStateList(stateSpecsArray, colorsArray);
+ }
}
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 9f8b974..d874270 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -29,7 +29,6 @@
import android.annotation.StyleableRes;
import android.app.LocaleConfig;
import android.app.ResourcesManager;
-import android.app.ResourcesManager.SharedLibraryAssets;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.Config;
@@ -48,8 +47,6 @@
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.os.Trace;
-import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -72,7 +69,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
@@ -149,10 +145,9 @@
// Cyclical cache used for recently-accessed XML files.
private int mLastCachedXmlBlockIndex = -1;
- // The number of shared libraries registered within this ResourcesImpl, which is designed to
- // help to determine whether this ResourcesImpl is outdated on shared library information and
- // needs to be replaced.
- private int mSharedLibCount;
+ // The hash that allows to detect when the shared libraries applied to this object have changed,
+ // and it is outdated and needs to be replaced.
+ private final int mAppliedSharedLibsHash;
private final int[] mCachedXmlBlockCookies = new int[XML_BLOCK_CACHE_SIZE];
private final String[] mCachedXmlBlockFiles = new String[XML_BLOCK_CACHE_SIZE];
private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[XML_BLOCK_CACHE_SIZE];
@@ -206,23 +201,8 @@
public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics,
@Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) {
mAssets = assets;
- if (Flags.registerResourcePaths()) {
- final ArraySet<String> uniquePaths = new ArraySet<>();
- final ArrayList<String> orderedPaths = new ArrayList<>();
- final ArrayMap<String, SharedLibraryAssets> sharedLibMap =
- ResourcesManager.getInstance().getSharedLibAssetsMap();
- final int size = sharedLibMap.size();
- for (int i = 0; i < size; i++) {
- final var paths = sharedLibMap.valueAt(i).getAllAssetPaths();
- for (int j = 0; j < paths.length; j++) {
- if (uniquePaths.add(paths[j])) {
- orderedPaths.add(paths[j]);
- }
- }
- }
- assets.addSharedLibraryPaths(orderedPaths);
- mSharedLibCount = size;
- }
+ mAppliedSharedLibsHash =
+ ResourcesManager.getInstance().updateResourceImplWithRegisteredLibs(this);
mMetrics.setToDefaults();
mDisplayAdjustments = displayAdjustments;
mConfiguration.setToDefaults();
@@ -1625,7 +1605,7 @@
}
}
- public int getSharedLibCount() {
- return mSharedLibCount;
+ public int getAppliedSharedLibsHash() {
+ return mAppliedSharedLibsHash;
}
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index c2424e8..cbac912 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -32,6 +32,7 @@
import android.app.AppOpsManager;
import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource.ScopedParcelState;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Point;
@@ -45,6 +46,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.Parcel;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -293,10 +295,14 @@
@SuppressLint("UnflaggedApi") // @TestApi without associated feature.
@TestApi
public static int getNumberOfCameras(@NonNull Context context) {
- return _getNumberOfCameras(context.getDeviceId(), getDevicePolicyFromContext(context));
+ try (ScopedParcelState clientAttribution =
+ context.getAttributionSource().asScopedParcelState()) {
+ return _getNumberOfCameras(
+ clientAttribution.getParcel(), getDevicePolicyFromContext(context));
+ }
}
- private static native int _getNumberOfCameras(int deviceId, int devicePolicy);
+ private static native int _getNumberOfCameras(Parcel clientAttributionParcel, int devicePolicy);
/**
* Returns the information about a particular camera.
@@ -321,8 +327,16 @@
@TestApi
public static void getCameraInfo(int cameraId, @NonNull Context context,
int rotationOverride, CameraInfo cameraInfo) {
- _getCameraInfo(cameraId, rotationOverride, context.getDeviceId(),
- getDevicePolicyFromContext(context), cameraInfo);
+ try (ScopedParcelState clientAttribution =
+ context.getAttributionSource().asScopedParcelState()) {
+ _getCameraInfo(
+ cameraId,
+ rotationOverride,
+ clientAttribution.getParcel(),
+ getDevicePolicyFromContext(context),
+ cameraInfo);
+ }
+
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
IAudioService audioService = IAudioService.Stub.asInterface(b);
try {
@@ -336,8 +350,12 @@
}
}
- private native static void _getCameraInfo(int cameraId, int rotationOverride,
- int deviceId, int devicePolicy, CameraInfo cameraInfo);
+ private native static void _getCameraInfo(
+ int cameraId,
+ int rotationOverride,
+ Parcel clientAttributionParcel,
+ int devicePolicy,
+ CameraInfo cameraInfo);
private static int getDevicePolicyFromContext(Context context) {
if (context.getDeviceId() == DEVICE_ID_DEFAULT
@@ -545,9 +563,18 @@
}
boolean forceSlowJpegMode = shouldForceSlowJpegMode();
- return native_setup(new WeakReference<>(this), cameraId,
- ActivityThread.currentOpPackageName(), rotationOverride, forceSlowJpegMode,
- context.getDeviceId(), getDevicePolicyFromContext(context));
+
+ try (ScopedParcelState clientAttribution =
+ context.getAttributionSource().asScopedParcelState()) {
+ return native_setup(
+ new WeakReference<>(this),
+ cameraId,
+ ActivityThread.currentOpPackageName(),
+ rotationOverride,
+ forceSlowJpegMode,
+ clientAttribution.getParcel(),
+ getDevicePolicyFromContext(context));
+ }
}
private boolean shouldForceSlowJpegMode() {
@@ -630,8 +657,14 @@
}
@UnsupportedAppUsage
- private native int native_setup(Object cameraThis, int cameraId, String packageName,
- int rotationOverride, boolean forceSlowJpegMode, int deviceId, int devicePolicy);
+ private native int native_setup(
+ Object cameraThis,
+ int cameraId,
+ String packageName,
+ int rotationOverride,
+ boolean forceSlowJpegMode,
+ Parcel clientAttributionParcel,
+ int devicePolicy);
private native final void native_release();
@@ -2267,9 +2300,11 @@
private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation";
private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step";
private static final String KEY_AUTO_EXPOSURE_LOCK = "auto-exposure-lock";
- private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED = "auto-exposure-lock-supported";
+ private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED =
+ "auto-exposure-lock-supported";
private static final String KEY_AUTO_WHITEBALANCE_LOCK = "auto-whitebalance-lock";
- private static final String KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED = "auto-whitebalance-lock-supported";
+ private static final String KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED =
+ "auto-whitebalance-lock-supported";
private static final String KEY_METERING_AREAS = "metering-areas";
private static final String KEY_MAX_NUM_METERING_AREAS = "max-num-metering-areas";
private static final String KEY_ZOOM = "zoom";
@@ -2286,7 +2321,8 @@
private static final String KEY_RECORDING_HINT = "recording-hint";
private static final String KEY_VIDEO_SNAPSHOT_SUPPORTED = "video-snapshot-supported";
private static final String KEY_VIDEO_STABILIZATION = "video-stabilization";
- private static final String KEY_VIDEO_STABILIZATION_SUPPORTED = "video-stabilization-supported";
+ private static final String KEY_VIDEO_STABILIZATION_SUPPORTED =
+ "video-stabilization-supported";
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 6fffb82..056ca93 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -564,7 +564,7 @@
* {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, then this list will only contain
* CONTROL_ZOOM_RATIO_RANGE and SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
*
- * @see INFO_SESSION_CONFIGURATION_QUERY_VERSION
+ * @see #INFO_SESSION_CONFIGURATION_QUERY_VERSION
*/
@NonNull
@FlaggedApi(Flags.FLAG_FEATURE_COMBINATION_QUERY)
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 9eb9745..2dbd4b8 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -35,6 +35,7 @@
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.Overridable;
+import android.content.AttributionSourceState;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Point;
@@ -106,6 +107,7 @@
private final boolean DEBUG = false;
private static final int USE_CALLING_UID = -1;
+ private static final int USE_CALLING_PID = -1;
@SuppressWarnings("unused")
private static final int API_VERSION_1 = 1;
@@ -418,9 +420,12 @@
public boolean isConcurrentSessionConfigurationSupported(
@NonNull Map<String, SessionConfiguration> cameraIdAndSessionConfig)
throws CameraAccessException {
- return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported(
- cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion,
- mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
+ return CameraManagerGlobal.get()
+ .isConcurrentSessionConfigurationSupported(
+ cameraIdAndSessionConfig,
+ mContext.getApplicationInfo().targetSdkVersion,
+ getClientAttribution(),
+ getDevicePolicyFromContext(mContext));
}
/**
@@ -660,11 +665,14 @@
}
try {
for (String physicalCameraId : physicalCameraIds) {
+ AttributionSourceState clientAttribution = getClientAttribution();
+ clientAttribution.deviceId = DEVICE_ID_DEFAULT;
CameraMetadataNative physicalCameraInfo =
- cameraService.getCameraCharacteristics(physicalCameraId,
+ cameraService.getCameraCharacteristics(
+ physicalCameraId,
mContext.getApplicationInfo().targetSdkVersion,
/*rotationOverride*/ ICameraService.ROTATION_OVERRIDE_NONE,
- DEVICE_ID_DEFAULT,
+ clientAttribution,
DEVICE_POLICY_DEFAULT);
StreamConfiguration[] configs = physicalCameraInfo.get(
CameraCharacteristics.
@@ -756,9 +764,13 @@
"Camera service is currently unavailable");
}
try {
- CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
- mContext.getApplicationInfo().targetSdkVersion, rotationOverride,
- mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
+ CameraMetadataNative info =
+ cameraService.getCameraCharacteristics(
+ cameraId,
+ mContext.getApplicationInfo().targetSdkVersion,
+ rotationOverride,
+ getClientAttribution(),
+ getDevicePolicyFromContext(mContext));
characteristics = prepareCameraCharacteristics(cameraId, info, cameraService);
} catch (ServiceSpecificException e) {
throw ExceptionUtils.throwAsPublicException(e);
@@ -951,15 +963,33 @@
}
/**
+ * Constructs an AttributionSourceState with only the uid, pid, and deviceId fields set
+ *
+ * <p>This method is a temporary stopgap in the transition to using AttributionSource. Currently
+ * AttributionSourceState is only used as a vehicle for passing deviceId, uid, and pid
+ * arguments.</p>
+ *
+ * @hide
+ */
+ public AttributionSourceState getClientAttribution() {
+ // TODO: Send the full contextAttribution over aidl, remove USE_CALLING_*
+ AttributionSourceState contextAttribution =
+ mContext.getAttributionSource().asState();
+ AttributionSourceState clientAttribution =
+ new AttributionSourceState();
+ clientAttribution.uid = USE_CALLING_UID;
+ clientAttribution.pid = USE_CALLING_PID;
+ clientAttribution.deviceId = contextAttribution.deviceId;
+ clientAttribution.next = new AttributionSourceState[0];
+ return clientAttribution;
+ }
+
+ /**
* Helper for opening a connection to a camera with the given ID.
*
* @param cameraId The unique identifier of the camera device to open
* @param callback The callback for the camera. Must not be null.
* @param executor The executor to invoke the callback with. Must not be null.
- * @param uid The UID of the application actually opening the camera.
- * Must be USE_CALLING_UID unless the caller is a service
- * that is trusted to open the device on behalf of an
- * application and to forward the real UID.
*
* @throws CameraAccessException if the camera is disabled by device policy,
* too many camera devices are already open, or the cameraId does not match
@@ -974,7 +1004,7 @@
* @see android.app.admin.DevicePolicyManager#setCameraDisabled
*/
private CameraDevice openCameraDeviceUserAsync(String cameraId,
- CameraDevice.StateCallback callback, Executor executor, final int uid,
+ CameraDevice.StateCallback callback, Executor executor,
final int oomScoreOffset, int rotationOverride) throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
@@ -1005,11 +1035,19 @@
"Camera service is currently unavailable");
}
- cameraUser = cameraService.connectDevice(callbacks, cameraId,
- mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
- oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
- rotationOverride, mContext.getDeviceId(),
- getDevicePolicyFromContext(mContext));
+ AttributionSourceState clientAttribution =
+ getClientAttribution();
+ cameraUser =
+ cameraService.connectDevice(
+ callbacks,
+ cameraId,
+ mContext.getOpPackageName(),
+ mContext.getAttributionTag(),
+ oomScoreOffset,
+ mContext.getApplicationInfo().targetSdkVersion,
+ rotationOverride,
+ clientAttribution,
+ getDevicePolicyFromContext(mContext));
} catch (ServiceSpecificException e) {
if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
throw new AssertionError("Should've gone down the shim path");
@@ -1135,8 +1173,8 @@
public void openCamera(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
throws CameraAccessException {
- openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
- USE_CALLING_UID);
+
+ openCameraImpl(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler));
}
/**
@@ -1172,8 +1210,8 @@
public void openCamera(@NonNull String cameraId, boolean overrideToPortrait,
@Nullable Handler handler,
@NonNull final CameraDevice.StateCallback callback) throws CameraAccessException {
- openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
- USE_CALLING_UID, /*oomScoreOffset*/0,
+ openCameraImpl(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
+ /*oomScoreOffset*/0,
overrideToPortrait
? ICameraService.ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT
: ICameraService.ROTATION_OVERRIDE_NONE);
@@ -1221,7 +1259,7 @@
if (executor == null) {
throw new IllegalArgumentException("executor was null");
}
- openCameraForUid(cameraId, callback, executor, USE_CALLING_UID);
+ openCameraImpl(cameraId, callback, executor);
}
/**
@@ -1289,13 +1327,13 @@
throw new IllegalArgumentException(
"oomScoreOffset < 0, cannot increase priority of camera client");
}
- openCameraForUid(cameraId, callback, executor, USE_CALLING_UID, oomScoreOffset,
+ openCameraImpl(cameraId, callback, executor, oomScoreOffset,
getRotationOverride(mContext));
}
/**
- * Open a connection to a camera with the given ID, on behalf of another application
- * specified by clientUid. Also specify the minimum oom score and process state the application
+ * Open a connection to a camera with the given ID, on behalf of another application.
+ * Also specify the minimum oom score and process state the application
* should have, as seen by the cameraserver.
*
* <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
@@ -1303,9 +1341,6 @@
* done by services trusted by the camera subsystem to act on behalf of applications and
* to forward the real UID.</p>
*
- * @param clientUid
- * The UID of the application on whose behalf the camera is being opened.
- * Must be USE_CALLING_UID unless the caller is a trusted service.
* @param oomScoreOffset
* The minimum oom score that cameraservice must see for this client.
* @param rotationOverride
@@ -1313,9 +1348,9 @@
* that should be followed for this camera id connection
* @hide
*/
- public void openCameraForUid(@NonNull String cameraId,
+ public void openCameraImpl(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
- int clientUid, int oomScoreOffset, int rotationOverride)
+ int oomScoreOffset, int rotationOverride)
throws CameraAccessException {
if (cameraId == null) {
@@ -1327,29 +1362,24 @@
throw new IllegalArgumentException("No cameras available on device");
}
- openCameraDeviceUserAsync(cameraId, callback, executor, clientUid, oomScoreOffset,
+ openCameraDeviceUserAsync(cameraId, callback, executor, oomScoreOffset,
rotationOverride);
}
/**
- * Open a connection to a camera with the given ID, on behalf of another application
- * specified by clientUid.
+ * Open a connection to a camera with the given ID, on behalf of another application.
*
* <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
* the caller to specify the UID to use for permission/etc verification. This can only be
* done by services trusted by the camera subsystem to act on behalf of applications and
* to forward the real UID.</p>
*
- * @param clientUid
- * The UID of the application on whose behalf the camera is being opened.
- * Must be USE_CALLING_UID unless the caller is a trusted service.
- *
* @hide
*/
- public void openCameraForUid(@NonNull String cameraId,
- @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
- int clientUid) throws CameraAccessException {
- openCameraForUid(cameraId, callback, executor, clientUid, /*oomScoreOffset*/0,
+ public void openCameraImpl(@NonNull String cameraId,
+ @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor)
+ throws CameraAccessException {
+ openCameraImpl(cameraId, callback, executor, /*oomScoreOffset*/0,
getRotationOverride(mContext));
}
@@ -1397,8 +1427,12 @@
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No cameras available on device");
}
- CameraManagerGlobal.get().setTorchMode(cameraId, enabled, mContext.getDeviceId(),
- getDevicePolicyFromContext(mContext));
+ CameraManagerGlobal.get()
+ .setTorchMode(
+ cameraId,
+ enabled,
+ getClientAttribution(),
+ getDevicePolicyFromContext(mContext));
}
/**
@@ -1461,8 +1495,12 @@
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No camera available on device");
}
- CameraManagerGlobal.get().turnOnTorchWithStrengthLevel(cameraId, torchStrength,
- mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
+ CameraManagerGlobal.get()
+ .turnOnTorchWithStrengthLevel(
+ cameraId,
+ torchStrength,
+ getClientAttribution(),
+ getDevicePolicyFromContext(mContext));
}
/**
@@ -1488,8 +1526,11 @@
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No camera available on device.");
}
- return CameraManagerGlobal.get().getTorchStrengthLevel(cameraId, mContext.getDeviceId(),
- getDevicePolicyFromContext(mContext));
+ return CameraManagerGlobal.get()
+ .getTorchStrengthLevel(
+ cameraId,
+ getClientAttribution(),
+ getDevicePolicyFromContext(mContext));
}
/**
@@ -2499,7 +2540,9 @@
public boolean isConcurrentSessionConfigurationSupported(
@NonNull Map<String, SessionConfiguration> cameraIdsAndSessionConfigurations,
- int targetSdkVersion, int deviceId, int devicePolicy)
+ int targetSdkVersion,
+ AttributionSourceState clientAttribution,
+ int devicePolicy)
throws CameraAccessException {
if (cameraIdsAndSessionConfigurations == null) {
throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null");
@@ -2517,9 +2560,12 @@
for (Set<DeviceCameraInfo> combination : mConcurrentCameraIdCombinations) {
Set<DeviceCameraInfo> infos = new ArraySet<>();
for (String cameraId : cameraIdsAndSessionConfigurations.keySet()) {
- infos.add(new DeviceCameraInfo(cameraId,
- devicePolicy == DEVICE_POLICY_DEFAULT
- ? DEVICE_ID_DEFAULT : deviceId));
+ infos.add(
+ new DeviceCameraInfo(
+ cameraId,
+ devicePolicy == DEVICE_POLICY_DEFAULT
+ ? DEVICE_ID_DEFAULT
+ : clientAttribution.deviceId));
}
if (combination.containsAll(infos)) {
subsetFound = true;
@@ -2541,7 +2587,7 @@
}
try {
return mCameraService.isConcurrentSessionConfigurationSupported(
- cameraIdsAndConfigs, targetSdkVersion, deviceId, devicePolicy);
+ cameraIdsAndConfigs, targetSdkVersion, clientAttribution, devicePolicy);
} catch (ServiceSpecificException e) {
throw ExceptionUtils.throwAsPublicException(e);
} catch (RemoteException e) {
@@ -2580,7 +2626,11 @@
return false;
}
- public void setTorchMode(String cameraId, boolean enabled, int deviceId, int devicePolicy)
+ public void setTorchMode(
+ String cameraId,
+ boolean enabled,
+ AttributionSourceState clientAttribution,
+ int devicePolicy)
throws CameraAccessException {
synchronized (mLock) {
if (cameraId == null) {
@@ -2594,8 +2644,8 @@
}
try {
- cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder, deviceId,
- devicePolicy);
+ cameraService.setTorchMode(
+ cameraId, enabled, mTorchClientBinder, clientAttribution, devicePolicy);
} catch(ServiceSpecificException e) {
throw ExceptionUtils.throwAsPublicException(e);
} catch (RemoteException e) {
@@ -2605,7 +2655,10 @@
}
}
- public void turnOnTorchWithStrengthLevel(String cameraId, int torchStrength, int deviceId,
+ public void turnOnTorchWithStrengthLevel(
+ String cameraId,
+ int torchStrength,
+ AttributionSourceState clientAttribution,
int devicePolicy)
throws CameraAccessException {
synchronized (mLock) {
@@ -2620,8 +2673,12 @@
}
try {
- cameraService.turnOnTorchWithStrengthLevel(cameraId, torchStrength,
- mTorchClientBinder, deviceId, devicePolicy);
+ cameraService.turnOnTorchWithStrengthLevel(
+ cameraId,
+ torchStrength,
+ mTorchClientBinder,
+ clientAttribution,
+ devicePolicy);
} catch(ServiceSpecificException e) {
throw ExceptionUtils.throwAsPublicException(e);
} catch (RemoteException e) {
@@ -2631,7 +2688,8 @@
}
}
- public int getTorchStrengthLevel(String cameraId, int deviceId, int devicePolicy)
+ public int getTorchStrengthLevel(
+ String cameraId, AttributionSourceState clientAttribution, int devicePolicy)
throws CameraAccessException {
int torchStrength;
synchronized (mLock) {
@@ -2646,8 +2704,9 @@
}
try {
- torchStrength = cameraService.getTorchStrengthLevel(cameraId, deviceId,
- devicePolicy);
+ torchStrength =
+ cameraService.getTorchStrengthLevel(
+ cameraId, clientAttribution, devicePolicy);
} catch(ServiceSpecificException e) {
throw ExceptionUtils.throwAsPublicException(e);
} catch (RemoteException e) {
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 6968f27..fbed50a 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -57,7 +57,7 @@
*
* <p>CaptureRequests can be created by using a {@link Builder} instance,
* obtained by calling {@link CameraDevice#createCaptureRequest} or {@link
- * CameraManager#createCaptureRequest}</p>
+ * CameraDevice.CameraDeviceSetup#createCaptureRequest}</p>
*
* <p>CaptureRequests are given to {@link CameraCaptureSession#capture} or
* {@link CameraCaptureSession#setRepeatingRequest} to capture images from a camera.</p>
@@ -84,7 +84,7 @@
* @see CameraCaptureSession#setRepeatingBurst
* @see CameraDevice#createCaptureRequest
* @see CameraDevice#createReprocessCaptureRequest
- * @see CameraManager#createCaptureRequest
+ * @see CameraDevice.CameraDeviceSetup#createCaptureRequest
*/
public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
implements Parcelable {
@@ -812,8 +812,9 @@
* A builder for capture requests.
*
* <p>To obtain a builder instance, use the
- * {@link CameraDevice#createCaptureRequest} or {@link CameraManager#createCaptureRequest}
- * method, which initializes the request fields to one of the templates defined in
+ * {@link CameraDevice#createCaptureRequest} or
+ * {@link CameraDevice.CameraDeviceSetup#createCaptureRequest} method, which
+ * initializes the request fields to one of the templates defined in
* {@link CameraDevice}.
*
* @see CameraDevice#createCaptureRequest
@@ -822,7 +823,7 @@
* @see CameraDevice#TEMPLATE_STILL_CAPTURE
* @see CameraDevice#TEMPLATE_VIDEO_SNAPSHOT
* @see CameraDevice#TEMPLATE_MANUAL
- * @see CameraManager#createCaptureRequest
+ * @see CameraDevice.CameraDeviceSetup#createCaptureRequest
*/
public final static class Builder {
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
index df057a1..4ddf602 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
@@ -71,9 +71,12 @@
}
try {
- CameraMetadataNative defaultRequest = cameraService.createDefaultRequest(mCameraId,
- templateType, mContext.getDeviceId(),
- mCameraManager.getDevicePolicyFromContext(mContext));
+ CameraMetadataNative defaultRequest =
+ cameraService.createDefaultRequest(
+ mCameraId,
+ templateType,
+ mCameraManager.getClientAttribution(),
+ mCameraManager.getDevicePolicyFromContext(mContext));
CameraDeviceImpl.disableZslIfNeeded(defaultRequest, mTargetSdkVersion,
templateType);
@@ -104,9 +107,11 @@
}
try {
- return cameraService.isSessionConfigurationWithParametersSupported(mCameraId,
- mTargetSdkVersion, config,
- mContext.getDeviceId(),
+ return cameraService.isSessionConfigurationWithParametersSupported(
+ mCameraId,
+ mTargetSdkVersion,
+ config,
+ mCameraManager.getClientAttribution(),
mCameraManager.getDevicePolicyFromContext(mContext));
} catch (ServiceSpecificException e) {
throw ExceptionUtils.throwAsPublicException(e);
@@ -133,12 +138,14 @@
}
try {
- CameraMetadataNative metadata = cameraService.getSessionCharacteristics(
- mCameraId, mTargetSdkVersion,
- CameraManager.getRotationOverride(mContext),
- sessionConfig,
- mContext.getDeviceId(),
- mCameraManager.getDevicePolicyFromContext(mContext));
+ CameraMetadataNative metadata =
+ cameraService.getSessionCharacteristics(
+ mCameraId,
+ mTargetSdkVersion,
+ CameraManager.getRotationOverride(mContext),
+ sessionConfig,
+ mCameraManager.getClientAttribution(),
+ mCameraManager.getDevicePolicyFromContext(mContext));
return mCameraManager.prepareCameraCharacteristics(mCameraId, metadata,
cameraService);
diff --git a/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java b/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java
index 69a6e9b..bf3f59f 100644
--- a/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java
+++ b/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java
@@ -23,12 +23,13 @@
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraExtensionCharacteristics.Extension;
import android.hardware.camera2.CameraExtensionSession;
+import android.media.ImageReader;
+
+import com.android.internal.camera.flags.Flags;
import java.util.List;
import java.util.concurrent.Executor;
-import com.android.internal.camera.flags.Flags;
-
/**
* A class that aggregates all supported arguments for
* {@link CameraExtensionSession} initialization.
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index f3b7b91..fb2c2f0 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -260,7 +260,7 @@
* smaller sizes, then the resulting
* {@link android.hardware.camera2.params.SessionConfiguration session configuration} can
* be tested either by calling {@link CameraDevice#createCaptureSession} or
- * {@link CameraDeviceSetup#isSessionConfigurationSupported}.
+ * {@link CameraDevice.CameraDeviceSetup#isSessionConfigurationSupported}.
*
* @return non-modifiable ascending list of available sizes.
*/
diff --git a/core/java/android/hardware/camera2/params/SessionConfiguration.java b/core/java/android/hardware/camera2/params/SessionConfiguration.java
index 3b2913c..0c55ed5 100644
--- a/core/java/android/hardware/camera2/params/SessionConfiguration.java
+++ b/core/java/android/hardware/camera2/params/SessionConfiguration.java
@@ -130,8 +130,8 @@
* Create a new {@link SessionConfiguration} with sessionType and output configurations.
*
* <p>The SessionConfiguration objects created by this constructor can be used by
- * {@link CameraDeviceSetup.isSessionConfigurationSupported} and {@link
- * CameraDeviceSetup.getSessionCharacteristics} to query a camera device's feature
+ * {@link CameraDeviceSetup#isSessionConfigurationSupported} and {@link
+ * CameraDeviceSetup#getSessionCharacteristics} to query a camera device's feature
* combination support and session specific characteristics. For the SessionConfiguration
* object to be used to create a capture session, {@link #setStateCallback} must be called to
* specify the state callback function, and any incomplete OutputConfigurations must be
diff --git a/core/java/android/hardware/devicestate/feature/flags.aconfig b/core/java/android/hardware/devicestate/feature/flags.aconfig
index 12d3f94..a09c84d 100644
--- a/core/java/android/hardware/devicestate/feature/flags.aconfig
+++ b/core/java/android/hardware/devicestate/feature/flags.aconfig
@@ -8,4 +8,13 @@
description: "Updated DeviceState hasProperty API"
bug: "293636629"
is_fixed_read_only: true
+}
+
+flag {
+ name: "device_state_property_migration"
+ is_exported: true
+ namespace: "windowing_sdk"
+ description: "Client migration to updated DeviceStateManager API's"
+ bug: "336640888"
+ is_fixed_read_only: true
}
\ No newline at end of file
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 8519722..8748bb1 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -549,15 +549,20 @@
}
/**
- * Request to power a display ON or OFF.
+ * Request to power a display OFF or reset it to a power state it supposed to have.
+ * @param displayId the id of the display
+ * @param state one of {@link android.view.Display#STATE_UNKNOWN} (to reset the state to
+ * the one the display should have had now), {@link android.view.Display#STATE_OFF}.
+ * @return true if successful, false otherwise
* @hide
*/
@RequiresPermission("android.permission.MANAGE_DISPLAYS")
- public boolean requestDisplayPower(int displayId, boolean on) {
+ public boolean requestDisplayPower(int displayId, int state) {
try {
- return mDm.requestDisplayPower(displayId, on);
+ return mDm.requestDisplayPower(displayId, state);
} catch (RemoteException ex) {
- Log.e(TAG, "Error trying to request display power " + on, ex);
+ Log.e(TAG, "Error trying to request display power:"
+ + " state=" + state, ex);
return false;
}
}
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index b7c02b0..28c71d9 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -236,9 +236,9 @@
@EnforcePermission("MANAGE_DISPLAYS")
void disableConnectedDisplay(int displayId);
- // Request to power display ON or OFF.
+ // Request to power display OFF or reset it to a power state it supposed to have.
@EnforcePermission("MANAGE_DISPLAYS")
- boolean requestDisplayPower(int displayId, boolean on);
+ boolean requestDisplayPower(int displayId, int state);
// Restricts display modes to specified modeIds.
@EnforcePermission("RESTRICT_DISPLAY_MODES")
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 40d4fb6..1767d64 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -32,6 +32,7 @@
import android.os.CombinedVibration;
import android.hardware.input.IInputSensorEventListener;
import android.hardware.input.InputSensorInfo;
+import android.hardware.input.KeyGlyphMap;
import android.hardware.lights.Light;
import android.hardware.lights.LightState;
import android.os.IBinder;
@@ -236,4 +237,6 @@
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.MONITOR_STICKY_MODIFIER_STATE)")
void unregisterStickyModifierStateListener(IStickyModifierStateListener listener);
+
+ KeyGlyphMap getKeyGlyphMap(int deviceId);
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 21c9002..23e262c 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -19,6 +19,7 @@
import static com.android.input.flags.Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API;
import static com.android.input.flags.Flags.FLAG_DEVICE_ASSOCIATIONS;
import static com.android.hardware.input.Flags.keyboardLayoutPreviewFlag;
+import static com.android.hardware.input.Flags.keyboardGlyphMap;
import android.Manifest;
import android.annotation.FlaggedApi;
@@ -158,6 +159,34 @@
"android.hardware.input.metadata.KEYBOARD_LAYOUTS";
/**
+ * Broadcast Action: Query available keyboard glyph maps.
+ * <p>
+ * The input manager service locates available keyboard glyph maps
+ * by querying broadcast receivers that are registered for this action.
+ * An application can offer additional keyboard glyph maps to the user
+ * by declaring a suitable broadcast receiver in its manifest.
+ * </p>
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_QUERY_KEYBOARD_GLYPH_MAPS =
+ "android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS";
+
+ /**
+ * Metadata Key: Keyboard glyph map metadata associated with
+ * {@link #ACTION_QUERY_KEYBOARD_GLYPH_MAPS}.
+ * <p>
+ * Specifies the resource id of a XML resource that describes the keyboard
+ * glyph maps that are provided by the application.
+ * </p>
+ *
+ * @hide
+ */
+ public static final String META_DATA_KEYBOARD_GLYPH_MAPS =
+ "android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS";
+
+ /**
* Prevent touches from being consumed by apps if these touches passed through a non-trusted
* window from a different UID and are considered unsafe.
*
@@ -898,6 +927,23 @@
}
/**
+ * Provides associated glyph map for the keyboard device (if available)
+ *
+ * @hide
+ */
+ @Nullable
+ public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+ if (!keyboardGlyphMap()) {
+ return null;
+ }
+ try {
+ return mIm.getKeyGlyphMap(deviceId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Injects an input event into the event system, targeting windows owned by the provided uid.
*
* If a valid targetUid is provided, the system will only consider injecting the input event
diff --git a/core/java/android/hardware/input/KeyGlyphMap.aidl b/core/java/android/hardware/input/KeyGlyphMap.aidl
new file mode 100644
index 0000000..104f1e4
--- /dev/null
+++ b/core/java/android/hardware/input/KeyGlyphMap.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2024 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 android.hardware.input;
+
+parcelable KeyGlyphMap;
\ No newline at end of file
diff --git a/core/java/android/hardware/input/KeyGlyphMap.java b/core/java/android/hardware/input/KeyGlyphMap.java
new file mode 100644
index 0000000..49c47a2
--- /dev/null
+++ b/core/java/android/hardware/input/KeyGlyphMap.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2024 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 android.hardware.input;
+
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.KeyEvent;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class provides access to device specific key glyphs, modifier glyphs and device specific
+ * shortcuts and keys
+ *
+ * @hide
+ */
+public final class KeyGlyphMap implements Parcelable {
+ private static final String TAG = "KeyGlyphMap";
+
+ @NonNull
+ private final ComponentName mComponentName;
+ @NonNull
+ private final SparseIntArray mKeyGlyphs;
+ @NonNull
+ private final SparseIntArray mModifierGlyphs;
+ @NonNull
+ private final int[] mFunctionRowKeys;
+ @NonNull
+ private final Map<KeyCombination, Integer> mHardwareShortcuts;
+
+ public static final @NonNull Parcelable.Creator<KeyGlyphMap> CREATOR =
+ new Parcelable.Creator<>() {
+ public KeyGlyphMap createFromParcel(Parcel in) {
+ return new KeyGlyphMap(in);
+ }
+
+ public KeyGlyphMap[] newArray(int size) {
+ return new KeyGlyphMap[size];
+ }
+ };
+
+ public KeyGlyphMap(@NonNull ComponentName componentName,
+ @NonNull SparseIntArray keyGlyphs, @NonNull SparseIntArray modifierGlyphs,
+ @NonNull int[] functionRowKeys,
+ @NonNull Map<KeyCombination, Integer> hardwareShortcuts) {
+ mComponentName = componentName;
+ mKeyGlyphs = keyGlyphs;
+ mModifierGlyphs = modifierGlyphs;
+ mFunctionRowKeys = functionRowKeys;
+ mHardwareShortcuts = hardwareShortcuts;
+ }
+
+ public KeyGlyphMap(Parcel in) {
+ mComponentName = in.readParcelable(getClass().getClassLoader(), ComponentName.class);
+ mKeyGlyphs = in.readSparseIntArray();
+ mModifierGlyphs = in.readSparseIntArray();
+ mFunctionRowKeys = new int[in.readInt()];
+ in.readIntArray(mFunctionRowKeys);
+ mHardwareShortcuts = new HashMap<>(in.readInt());
+ in.readMap(mHardwareShortcuts, getClass().getClassLoader(), KeyCombination.class,
+ Integer.class);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeParcelable(mComponentName, 0);
+ dest.writeSparseIntArray(mKeyGlyphs);
+ dest.writeSparseIntArray(mModifierGlyphs);
+ dest.writeInt(mFunctionRowKeys.length);
+ dest.writeIntArray(mFunctionRowKeys);
+ dest.writeInt(mHardwareShortcuts.size());
+ dest.writeMap(mHardwareShortcuts);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Defines a key combination that includes a keycode and modifier state.
+ */
+ public record KeyCombination(int modifierState, int keycode) {}
+
+ /**
+ * Returns keycodes generated from the functional row defined for the keyboard.
+ */
+ public int[] getFunctionRowKeys() {
+ return mFunctionRowKeys;
+ }
+
+ /**
+ * Returns hardware defined shortcuts that are handled in the firmware of a particular
+ * keyboard (e.g. Fn+Backspace = Back, etc.)
+ *
+ * @return a map of (modifier + key) combinations to keycode mappings that are handled by the
+ * device hardware/firmware.
+ */
+ public Map<KeyCombination, Integer> getHardwareShortcuts() {
+ return mHardwareShortcuts;
+ }
+
+ /**
+ * Provides the drawable resource for the glyph for a keycode.
+ * Returns null if not available.
+ */
+ @Nullable
+ public Drawable getDrawableForKeycode(Context context, int keycode) {
+ return getDrawable(context, mKeyGlyphs.get(keycode, 0));
+ }
+
+ /**
+ * Provides the drawable resource for the glyph for a modifier key.
+ * Returns null if not available.
+ */
+ @Nullable
+ public Drawable getDrawableForModifier(Context context, int modifierKeycode) {
+ int modifier = switch (modifierKeycode) {
+ case KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_META_RIGHT -> KeyEvent.META_META_ON;
+ case KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_CTRL_RIGHT -> KeyEvent.META_CTRL_ON;
+ case KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT -> KeyEvent.META_ALT_ON;
+ case KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT ->
+ KeyEvent.META_SHIFT_ON;
+ case KeyEvent.KEYCODE_FUNCTION -> KeyEvent.META_FUNCTION_ON;
+ case KeyEvent.KEYCODE_SYM -> KeyEvent.META_SYM_ON;
+ case KeyEvent.KEYCODE_CAPS_LOCK -> KeyEvent.META_CAPS_LOCK_ON;
+ case KeyEvent.KEYCODE_NUM_LOCK -> KeyEvent.META_NUM_LOCK_ON;
+ case KeyEvent.KEYCODE_SCROLL_LOCK -> KeyEvent.META_SCROLL_LOCK_ON;
+ default -> 0;
+ };
+ return getDrawable(context, mModifierGlyphs.get(modifier, 0));
+ }
+
+ @Nullable
+ private Drawable getDrawable(Context context, @DrawableRes int drawableRes) {
+ PackageManager pm = context.getPackageManager();
+ try {
+ ActivityInfo receiver = pm.getReceiverInfo(mComponentName,
+ PackageManager.GET_META_DATA
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+ Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+ return resources.getDrawable(drawableRes, null);
+ } catch (PackageManager.NameNotFoundException ignored) {
+ Log.e(TAG, "Package name not found for " + mComponentName);
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "KeyGlyphMap{"
+ + "mComponentName=" + mComponentName
+ + ", mKeyGlyphs=" + mKeyGlyphs
+ + ", mModifierGlyphs=" + mModifierGlyphs
+ + ", mFunctionRowKeys=" + Arrays.toString(mFunctionRowKeys)
+ + ", mHardwareShortcuts=" + mHardwareShortcuts
+ + '}';
+ }
+}
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoder.java b/core/java/android/hardware/input/VirtualRotaryEncoder.java
new file mode 100644
index 0000000..bc131df
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoder.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2024 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 android.hardware.input;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.companion.virtual.IVirtualDevice;
+import android.companion.virtualdevice.flags.Flags;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A virtual rotary encoder representing a scroll input mechanism on a remote device.
+ *
+ * <p>This registers an {@link android.view.InputDevice} that is interpreted like a
+ * physically-connected device and dispatches received events to it.</p>
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_VIRTUAL_ROTARY)
+@SystemApi
+public class VirtualRotaryEncoder extends VirtualInputDevice {
+ /** @hide */
+ public VirtualRotaryEncoder(VirtualRotaryEncoderConfig config, IVirtualDevice virtualDevice,
+ IBinder token) {
+ super(config, virtualDevice, token);
+ }
+
+ /**
+ * Sends a scroll event to the system.
+ *
+ * @param event the event to send
+ */
+ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ public void sendScrollEvent(@NonNull VirtualRotaryEncoderScrollEvent event) {
+ try {
+ if (!mVirtualDevice.sendRotaryEncoderScrollEvent(mToken, event)) {
+ Log.w(TAG, "Failed to send scroll event from virtual rotary "
+ + mConfig.getInputDeviceName());
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+}
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderConfig.aidl b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.aidl
new file mode 100644
index 0000000..2d9a899
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 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 android.hardware.input;
+
+parcelable VirtualRotaryEncoderConfig;
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderConfig.java b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.java
new file mode 100644
index 0000000..8d81fa9
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 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 android.hardware.input;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.companion.virtualdevice.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Configuration for creating a virtual rotary encoder.
+ *
+ * @see android.companion.virtual.VirtualDeviceManager.VirtualDevice#createVirtualRotaryEncoder
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_VIRTUAL_ROTARY)
+@SystemApi
+public final class VirtualRotaryEncoderConfig extends VirtualInputDeviceConfig
+ implements Parcelable {
+ @NonNull
+ public static final Creator<VirtualRotaryEncoderConfig> CREATOR = new Creator<>() {
+ @Override
+ public VirtualRotaryEncoderConfig createFromParcel(Parcel in) {
+ return new VirtualRotaryEncoderConfig(in);
+ }
+
+ @Override
+ public VirtualRotaryEncoderConfig[] newArray(int size) {
+ return new VirtualRotaryEncoderConfig[size];
+ }
+ };
+
+ private VirtualRotaryEncoderConfig(@NonNull VirtualRotaryEncoderConfig.Builder builder) {
+ super(builder);
+ }
+
+ private VirtualRotaryEncoderConfig(@NonNull Parcel in) {
+ super(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ }
+
+ /**
+ * Builder for creating a {@link VirtualRotaryEncoderConfig}.
+ */
+ public static final class Builder extends VirtualInputDeviceConfig.Builder<Builder> {
+
+ /**
+ * Builds the {@link VirtualRotaryEncoderConfig} instance.
+ */
+ @NonNull
+ public VirtualRotaryEncoderConfig build() {
+ return new VirtualRotaryEncoderConfig(this);
+ }
+ }
+}
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.aidl b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.aidl
new file mode 100644
index 0000000..0b238ee
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 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 android.hardware.input;
+
+parcelable VirtualRotaryEncoderScrollEvent;
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java
new file mode 100644
index 0000000..3be911abe7
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024 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 android.hardware.input;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.companion.virtualdevice.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.view.InputEvent;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * An event describing a rotary encoder scroll interaction originating from a remote device.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_VIRTUAL_ROTARY)
+@SystemApi
+public final class VirtualRotaryEncoderScrollEvent implements Parcelable {
+
+ private final float mScrollAmount;
+ private final long mEventTimeNanos;
+
+ private VirtualRotaryEncoderScrollEvent(float scrollAmount, long eventTimeNanos) {
+ mScrollAmount = scrollAmount;
+ mEventTimeNanos = eventTimeNanos;
+ }
+
+ private VirtualRotaryEncoderScrollEvent(@NonNull Parcel parcel) {
+ mScrollAmount = parcel.readFloat();
+ mEventTimeNanos = parcel.readLong();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int parcelableFlags) {
+ parcel.writeFloat(mScrollAmount);
+ parcel.writeLong(mEventTimeNanos);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return "VirtualRotaryScrollEvent("
+ + " scrollAmount=" + mScrollAmount
+ + " eventTime(ns)=" + mEventTimeNanos;
+ }
+
+ /**
+ * Returns the scroll amount, normalized from -1.0 to 1.0, inclusive.
+ * <p>
+ * Positive values indicate scrolling forward (e.g. down in a vertical list); negative values,
+ * backward.
+ * <p>
+ * Values of 1.0 or -1.0 represent the maximum supported scroll.
+ * </p>
+ */
+ public @FloatRange(from = -1.0f, to = 1.0f) float getScrollAmount() {
+ return mScrollAmount;
+ }
+
+ /**
+ * Returns the time this event occurred, in the {@link SystemClock#uptimeMillis()} time base but
+ * with nanosecond (instead of millisecond) precision.
+ *
+ * @see InputEvent#getEventTime()
+ */
+ public long getEventTimeNanos() {
+ return mEventTimeNanos;
+ }
+
+ /**
+ * Builder for {@link VirtualRotaryEncoderScrollEvent}.
+ */
+ public static final class Builder {
+
+ @FloatRange(from = -1.0f, to = 1.0f) private float mScrollAmount = 0.0f;
+ private long mEventTimeNanos = 0L;
+
+ /**
+ * Creates a {@link VirtualRotaryEncoderScrollEvent} object with the current configuration.
+ */
+ public @NonNull VirtualRotaryEncoderScrollEvent build() {
+ return new VirtualRotaryEncoderScrollEvent(mScrollAmount, mEventTimeNanos);
+ }
+
+ /**
+ * Sets the scroll amount, normalized from -1.0 to 1.0, inclusive.
+ * <p>
+ * Positive values indicate scrolling forward (e.g. down in a vertical list); negative
+ * values, backward.
+ * <p>
+ * Values of 1.0 or -1.0 represent the maximum supported scroll.
+ * </p>
+ * @return this builder, to allow for chaining of calls
+ */
+ public @NonNull Builder setScrollAmount(
+ @FloatRange(from = -1.0f, to = 1.0f) float scrollAmount) {
+ Preconditions.checkArgumentInRange(scrollAmount, -1f, 1f, "scrollAmount");
+ mScrollAmount = scrollAmount;
+ return this;
+ }
+
+ /**
+ * Sets the time (in nanoseconds) when this specific event was generated. This may be
+ * obtained from {@link SystemClock#uptimeMillis()} (with nanosecond precision instead of
+ * millisecond), but can be different depending on the use case.
+ * This field is optional and can be omitted.
+ *
+ * @return this builder, to allow for chaining of calls
+ * @see InputEvent#getEventTime()
+ */
+ public @NonNull Builder setEventTimeNanos(long eventTimeNanos) {
+ if (eventTimeNanos < 0L) {
+ throw new IllegalArgumentException("Event time cannot be negative");
+ }
+ mEventTimeNanos = eventTimeNanos;
+ return this;
+ }
+ }
+
+ public static final @NonNull Creator<VirtualRotaryEncoderScrollEvent> CREATOR =
+ new Creator<VirtualRotaryEncoderScrollEvent>() {
+ public VirtualRotaryEncoderScrollEvent createFromParcel(Parcel source) {
+ return new VirtualRotaryEncoderScrollEvent(source);
+ }
+
+ public VirtualRotaryEncoderScrollEvent[] newArray(int size) {
+ return new VirtualRotaryEncoderScrollEvent[size];
+ }
+ };
+}
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index ed536ce..acd0d00f 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -53,4 +53,11 @@
name: "touchpad_tap_dragging"
description: "Offers a setting to enable touchpad tap dragging"
bug: "321978150"
-}
\ No newline at end of file
+}
+
+flag {
+ namespace: "input_native"
+ name: "keyboard_glyph_map"
+ description: "Allows system to provide keyboard specific key drawables and shortcuts via config files"
+ bug: "345440920"
+}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 065b3d6..b2f333a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -9025,6 +9025,10 @@
final int uid = consumer.getUid();
final Uid u = uidStats.get(uid);
+ if (u == null) {
+ continue;
+ }
+
final long rxPackets = u.getNetworkActivityPackets(
BatteryStats.NETWORK_MOBILE_RX_DATA, STATS_SINCE_CHARGED);
final long txPackets = u.getNetworkActivityPackets(
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 90d82e7..61cc23d 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -870,6 +870,16 @@
}
/**
+ * Returns true if this Builder is configured to hold data for the specified
+ * custom power component ID.
+ */
+ public boolean isSupportedCustomPowerComponent(int componentId) {
+ return componentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+ && componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+ + mBatteryConsumerDataLayout.customPowerComponentCount;
+ }
+
+ /**
* Constructs a read-only object using the Builder values.
*/
@NonNull
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
new file mode 100644
index 0000000..72b5cf7
--- /dev/null
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -0,0 +1,1648 @@
+/*
+ * Copyright (C) 2024 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 android.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Handler;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Printer;
+import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Low-level class holding the list of messages to be dispatched by a
+ * {@link Looper}. Messages are not added directly to a MessageQueue,
+ * but rather through {@link Handler} objects associated with the Looper.
+ *
+ * <p>You can retrieve the MessageQueue for the current thread with
+ * {@link Looper#myQueue() Looper.myQueue()}.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
+ "com.android.platform.test.ravenwood.nativesubstitution.MessageQueue_host")
+public final class MessageQueue {
+ private static final String TAG = "ConcurrentMessageQueue";
+ private static final boolean DEBUG = false;
+ private static final boolean TRACE = false;
+
+ // True if the message queue can be quit.
+ private final boolean mQuitAllowed;
+
+ @SuppressWarnings("unused")
+ private long mPtr; // used by native code
+
+ @IntDef(value = {
+ STACK_NODE_MESSAGE,
+ STACK_NODE_ACTIVE,
+ STACK_NODE_PARKED,
+ STACK_NODE_TIMEDPARK})
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface StackNodeType {}
+
+ /*
+ * Stack node types. STACK_NODE_MESSAGE indicates a node containing a message.
+ * The other types indicate what state our Looper thread is in. The bottom of
+ * the stack is always a single state node. Message nodes are added on top.
+ */
+ private static final int STACK_NODE_MESSAGE = 0;
+ /*
+ * Active state indicates that next() is processing messages
+ */
+ private static final int STACK_NODE_ACTIVE = 1;
+ /*
+ * Parked state indicates that the Looper thread is sleeping indefinitely (nothing to deliver)
+ */
+ private static final int STACK_NODE_PARKED = 2;
+ /*
+ * Timed Park state indicates that the Looper thread is sleeping, waiting for a message
+ * deadline
+ */
+ private static final int STACK_NODE_TIMEDPARK = 3;
+
+ /* Describes a node in the Treiber stack */
+ static class StackNode {
+ @StackNodeType
+ private final int mType;
+
+ StackNode(@StackNodeType int type) {
+ mType = type;
+ }
+
+ @StackNodeType
+ final int getNodeType() {
+ return mType;
+ }
+
+ final boolean isMessageNode() {
+ return mType == STACK_NODE_MESSAGE;
+ }
+ }
+
+ static final class MessageNode extends StackNode implements Comparable<MessageNode> {
+ private final Message mMessage;
+ volatile StackNode mNext;
+ StateNode mBottomOfStack;
+ boolean mWokeUp;
+ final long mInsertSeq;
+ private static final VarHandle sRemovedFromStack;
+ private volatile boolean mRemovedFromStackValue;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sRemovedFromStack = l.findVarHandle(MessageQueue.MessageNode.class,
+ "mRemovedFromStackValue", boolean.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ MessageNode(@NonNull Message message, long insertSeq) {
+ super(STACK_NODE_MESSAGE);
+ mMessage = message;
+ mInsertSeq = insertSeq;
+ }
+
+ long getWhen() {
+ return mMessage.when;
+ }
+
+ boolean isRemovedFromStack() {
+ return mRemovedFromStackValue;
+ }
+
+ boolean removeFromStack() {
+ return sRemovedFromStack.compareAndSet(this, false, true);
+ }
+
+ boolean isAsync() {
+ return mMessage.isAsynchronous();
+ }
+
+ boolean isBarrier() {
+ return mMessage.target == null;
+ }
+
+ @Override
+ public int compareTo(@NonNull MessageNode messageNode) {
+ Message other = messageNode.mMessage;
+
+ int compared = Long.compare(mMessage.when, other.when);
+ if (compared == 0) {
+ compared = Long.compare(mInsertSeq, messageNode.mInsertSeq);
+ }
+ return compared;
+ }
+ }
+
+ static class StateNode extends StackNode {
+ StateNode(int type) {
+ super(type);
+ }
+ }
+
+ static final class TimedParkStateNode extends StateNode {
+ long mWhenToWake;
+
+ TimedParkStateNode() {
+ super(STACK_NODE_TIMEDPARK);
+ }
+ }
+
+ private static final StateNode sStackStateActive = new StateNode(STACK_NODE_ACTIVE);
+ private static final StateNode sStackStateParked = new StateNode(STACK_NODE_PARKED);
+ private final TimedParkStateNode mStackStateTimedPark = new TimedParkStateNode();
+
+ /* This is the top of our treiber stack. */
+ private static final VarHandle sState;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sState = l.findVarHandle(MessageQueue.class, "mStateValue",
+ MessageQueue.StackNode.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ private volatile StackNode mStateValue = sStackStateParked;
+ private final ConcurrentSkipListSet<MessageNode> mPriorityQueue =
+ new ConcurrentSkipListSet<MessageNode>();
+ private final ConcurrentSkipListSet<MessageNode> mAsyncPriorityQueue =
+ new ConcurrentSkipListSet<MessageNode>();
+
+ /*
+ * This helps us ensure that messages with the same timestamp are inserted in FIFO order.
+ * Increments on each insert, starting at 0. MessageNode.compareTo() will compare sequences
+ * when delivery timestamps are identical.
+ */
+ private static final VarHandle sNextInsertSeq;
+ private volatile long mNextInsertSeqValue = 0;
+ /*
+ * The exception to the FIFO order rule is sendMessageAtFrontOfQueue().
+ * Those messages must be in LIFO order - SIGH.
+ * Decrements on each front of queue insert.
+ */
+ private static final VarHandle sNextFrontInsertSeq;
+ private volatile long mNextFrontInsertSeqValue = -1;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sNextInsertSeq = l.findVarHandle(MessageQueue.class, "mNextInsertSeqValue",
+ long.class);
+ sNextFrontInsertSeq = l.findVarHandle(MessageQueue.class, "mNextFrontInsertSeqValue",
+ long.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+
+ }
+
+ /*
+ * Tracks the number of queued and cancelled messages in our stack.
+ *
+ * On item cancellation, determine whether to wake next() to flush tombstoned messages.
+ * We track queued and cancelled counts as two ints packed into a single long.
+ */
+ private static final class MessageCounts {
+ private static VarHandle sCounts;
+ private volatile long mCountsValue = 0;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sCounts = l.findVarHandle(MessageQueue.MessageCounts.class, "mCountsValue",
+ long.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ /* We use a special value to indicate when next() has been woken for flush. */
+ private static final long AWAKE = Long.MAX_VALUE;
+ /*
+ * Minimum number of messages in the stack which we need before we consider flushing
+ * tombstoned items.
+ */
+ private static final int MESSAGE_FLUSH_THRESHOLD = 10;
+
+ private static int numQueued(long val) {
+ return (int) (val >>> Integer.SIZE);
+ }
+
+ private static int numCancelled(long val) {
+ return (int) val;
+ }
+
+ private static long combineCounts(int queued, int cancelled) {
+ return ((long) queued << Integer.SIZE) | (long) cancelled;
+ }
+
+ public void incrementQueued() {
+ while (true) {
+ long oldVal = mCountsValue;
+ int queued = numQueued(oldVal);
+ int cancelled = numCancelled(oldVal);
+ /* Use Math.max() to avoid overflow of queued count */
+ long newVal = combineCounts(Math.max(queued + 1, queued), cancelled);
+
+ /* Don't overwrite 'AWAKE' state */
+ if (oldVal == AWAKE || sCounts.compareAndSet(this, oldVal, newVal)) {
+ break;
+ }
+ }
+ }
+
+ public boolean incrementCancelled() {
+ while (true) {
+ long oldVal = mCountsValue;
+ if (oldVal == AWAKE) {
+ return false;
+ }
+ int queued = numQueued(oldVal);
+ int cancelled = numCancelled(oldVal);
+ boolean needsPurge = queued > MESSAGE_FLUSH_THRESHOLD
+ && (queued >> 1) < cancelled;
+ long newVal;
+ if (needsPurge) {
+ newVal = AWAKE;
+ } else {
+ newVal = combineCounts(queued,
+ Math.max(cancelled + 1, cancelled));
+ }
+
+ if (sCounts.compareAndSet(this, oldVal, newVal)) {
+ return needsPurge;
+ }
+ }
+ }
+
+ public void clearCounts() {
+ mCountsValue = 0;
+ }
+ }
+
+ private final MessageCounts mMessageCounts = new MessageCounts();
+
+ private final Object mIdleHandlersLock = new Object();
+ @GuardedBy("mIdleHandlersLock")
+ private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
+ private IdleHandler[] mPendingIdleHandlers;
+
+ private final Object mFileDescriptorRecordsLock = new Object();
+ @GuardedBy("mFileDescriptorRecordsLock")
+ private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
+
+ private static final VarHandle sQuitting;
+ private boolean mQuittingValue = false;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sQuitting = l.findVarHandle(MessageQueue.class, "mQuittingValue", boolean.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ // The next barrier token.
+ // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+ private final AtomicInteger mNextBarrierToken = new AtomicInteger(1);
+
+ private static native long nativeInit();
+ private static native void nativeDestroy(long ptr);
+ private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
+ private static native void nativeWake(long ptr);
+ private static native boolean nativeIsPolling(long ptr);
+ private static native void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
+
+ MessageQueue(boolean quitAllowed) {
+ mQuitAllowed = quitAllowed;
+ mPtr = nativeInit();
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ dispose();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ // Disposes of the underlying message queue.
+ // Must only be called on the looper thread or the finalizer.
+ private void dispose() {
+ if (mPtr != 0) {
+ nativeDestroy(mPtr);
+ mPtr = 0;
+ }
+ }
+
+ /**
+ * Returns true if the looper has no pending messages which are due to be processed.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @return True if the looper is idle.
+ */
+ public boolean isIdle() {
+ MessageNode msgNode = null;
+ MessageNode asyncMsgNode = null;
+
+ if (!mPriorityQueue.isEmpty()) {
+ try {
+ msgNode = mPriorityQueue.first();
+ } catch (NoSuchElementException e) { }
+ }
+
+ if (!mAsyncPriorityQueue.isEmpty()) {
+ try {
+ asyncMsgNode = mAsyncPriorityQueue.first();
+ } catch (NoSuchElementException e) { }
+ }
+
+ final long now = SystemClock.uptimeMillis();
+ if ((msgNode != null && msgNode.getWhen() <= now)
+ || (asyncMsgNode != null && asyncMsgNode.getWhen() <= now)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /* Protects mNextIsDrainingStack */
+ private final ReentrantLock mDrainingLock = new ReentrantLock();
+ private boolean mNextIsDrainingStack = false;
+ private final Condition mDrainCompleted = mDrainingLock.newCondition();
+
+ /**
+ * Add a new {@link IdleHandler} to this message queue. This may be
+ * removed automatically for you by returning false from
+ * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
+ * invoked, or explicitly removing it with {@link #removeIdleHandler}.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @param handler The IdleHandler to be added.
+ */
+ public void addIdleHandler(@NonNull IdleHandler handler) {
+ if (handler == null) {
+ throw new NullPointerException("Can't add a null IdleHandler");
+ }
+ synchronized (mIdleHandlersLock) {
+ mIdleHandlers.add(handler);
+ }
+ }
+
+ /**
+ * Remove an {@link IdleHandler} from the queue that was previously added
+ * with {@link #addIdleHandler}. If the given object is not currently
+ * in the idle list, nothing is done.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @param handler The IdleHandler to be removed.
+ */
+ public void removeIdleHandler(@NonNull IdleHandler handler) {
+ synchronized (mIdleHandlersLock) {
+ mIdleHandlers.remove(handler);
+ }
+ }
+
+ /**
+ * Returns whether this looper's thread is currently polling for more work to do.
+ * This is a good signal that the loop is still alive rather than being stuck
+ * handling a callback. Note that this method is intrinsically racy, since the
+ * state of the loop can change before you get the result back.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @return True if the looper is currently polling for events.
+ * @hide
+ */
+ public boolean isPolling() {
+ // If the loop is quitting then it must not be idling.
+ // We can assume mPtr != 0 when sQuitting is false.
+ return !((boolean) sQuitting.getVolatile(this)) && nativeIsPolling(mPtr);
+ }
+
+ /* Helper to choose the correct queue to insert into. */
+ private void insertIntoPriorityQueue(MessageNode msgNode) {
+ if (msgNode.isAsync()) {
+ mAsyncPriorityQueue.add(msgNode);
+ } else {
+ mPriorityQueue.add(msgNode);
+ }
+ }
+
+ private boolean removeFromPriorityQueue(MessageNode msgNode) {
+ if (msgNode.isAsync()) {
+ return mAsyncPriorityQueue.remove(msgNode);
+ } else {
+ return mPriorityQueue.remove(msgNode);
+ }
+ }
+
+ private MessageNode pickEarliestNode(MessageNode nodeA, MessageNode nodeB) {
+ if (nodeA != null && nodeB != null) {
+ if (nodeA.compareTo(nodeB) < 0) {
+ return nodeA;
+ }
+ return nodeB;
+ }
+
+ return nodeA != null ? nodeA : nodeB;
+ }
+
+ private MessageNode iterateNext(Iterator<MessageNode> iter) {
+ if (iter.hasNext()) {
+ try {
+ return iter.next();
+ } catch (NoSuchElementException e) {
+ /* The queue is empty - this can happen if we race with remove */
+ }
+ }
+ return null;
+ }
+
+ /* Move any non-cancelled messages into the priority queue */
+ private void drainStack(StackNode oldTop) {
+ while (oldTop.isMessageNode()) {
+ MessageNode oldTopMessageNode = (MessageNode) oldTop;
+ if (oldTopMessageNode.removeFromStack()) {
+ insertIntoPriorityQueue(oldTopMessageNode);
+ }
+ MessageNode inserted = oldTopMessageNode;
+ oldTop = oldTopMessageNode.mNext;
+ /*
+ * removeMessages can walk this list while we are consuming it.
+ * Set our next pointer to null *after* we add the message to our
+ * priority queue. This way removeMessages() will always find the
+ * message, either in our list or in the priority queue.
+ */
+ inserted.mNext = null;
+ }
+ }
+
+ /* Set the stack state to Active, return a list of nodes to walk. */
+ private StackNode swapAndSetStackStateActive() {
+ while (true) {
+ /* Set stack state to Active, get node list to walk later */
+ StackNode current = (StackNode) sState.getVolatile(this);
+ if (current == sStackStateActive
+ || sState.compareAndSet(this, current, sStackStateActive)) {
+ return current;
+ }
+ }
+ }
+
+ /* This is only read/written from the Looper thread */
+ private int mNextPollTimeoutMillis;
+ private static final AtomicLong mMessagesDelivered = new AtomicLong();
+
+ private Message nextMessage() {
+ int i = 0;
+
+ while (true) {
+ if (DEBUG) {
+ Log.d(TAG, "nextMessage loop #" + i);
+ i++;
+ }
+
+ mDrainingLock.lock();
+ mNextIsDrainingStack = true;
+ mDrainingLock.unlock();
+
+ /*
+ * Set our state to active, drain any items from the stack into our priority queues
+ */
+ StackNode oldTop;
+ oldTop = swapAndSetStackStateActive();
+ drainStack(oldTop);
+
+ mDrainingLock.lock();
+ mNextIsDrainingStack = false;
+ mDrainCompleted.signalAll();
+ mDrainingLock.unlock();
+
+ /*
+ * The objective of this next block of code is to:
+ * - find a message to return (if any is ready)
+ * - find a next message we would like to return, after scheduling.
+ * - we make our scheduling decision based on this next message (if it exists).
+ *
+ * We have two queues to juggle and the presence of barriers throws an additional
+ * wrench into our plans.
+ *
+ * The last wrinkle is that remove() may delete items from underneath us. If we hit
+ * that case, we simply restart the loop.
+ */
+
+ /* Get the first node from each queue */
+ Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
+ MessageNode msgNode = iterateNext(queueIter);
+ Iterator<MessageNode> asyncQueueIter = mAsyncPriorityQueue.iterator();
+ MessageNode asyncMsgNode = iterateNext(asyncQueueIter);
+
+ if (DEBUG) {
+ if (msgNode != null) {
+ Message msg = msgNode.mMessage;
+ Log.d(TAG, "Next found node what: " + msg.what + " when: " + msg.when
+ + " seq: " + msgNode.mInsertSeq + "barrier: "
+ + msgNode.isBarrier() + " now: " + SystemClock.uptimeMillis());
+ }
+ if (asyncMsgNode != null) {
+ Message msg = asyncMsgNode.mMessage;
+ Log.d(TAG, "Next found async node what: " + msg.what + " when: " + msg.when
+ + " seq: " + asyncMsgNode.mInsertSeq + "barrier: "
+ + asyncMsgNode.isBarrier() + " now: "
+ + SystemClock.uptimeMillis());
+ }
+ }
+
+ /*
+ * the node which we will return, null if none are ready
+ */
+ MessageNode found = null;
+ /*
+ * The node from which we will determine our next wakeup time.
+ * Null indicates there is no next message ready. If we found a node,
+ * we can leave this null as Looper will call us again after delivering
+ * the message.
+ */
+ MessageNode next = null;
+
+ long now = SystemClock.uptimeMillis();
+ /*
+ * If we have a barrier we should return the async node (if it exists and is ready)
+ */
+ if (msgNode != null && msgNode.isBarrier()) {
+ if (asyncMsgNode != null && now >= asyncMsgNode.getWhen()) {
+ found = asyncMsgNode;
+ } else {
+ next = asyncMsgNode;
+ }
+ } else { /* No barrier. */
+ MessageNode earliest;
+ /*
+ * If we have two messages, pick the earliest option from either queue.
+ * Otherwise grab whichever node is non-null. If both are null we'll fall through.
+ */
+ earliest = pickEarliestNode(msgNode, asyncMsgNode);
+
+ if (earliest != null) {
+ if (now >= earliest.getWhen()) {
+ found = earliest;
+ } else {
+ next = earliest;
+ }
+ }
+ }
+
+ if (DEBUG) {
+ if (found != null) {
+ Message msg = found.mMessage;
+ Log.d(TAG, "Will deliver node what: " + msg.what + " when: " + msg.when
+ + " seq: " + found.mInsertSeq + " barrier: " + found.isBarrier()
+ + " async: " + found.isAsync() + " now: "
+ + SystemClock.uptimeMillis());
+ } else {
+ Log.d(TAG, "No node to deliver");
+ }
+ if (next != null) {
+ Message msg = next.mMessage;
+ Log.d(TAG, "Next node what: " + msg.what + " when: " + msg.when + " seq: "
+ + next.mInsertSeq + " barrier: " + next.isBarrier() + " async: "
+ + next.isAsync()
+ + " now: " + SystemClock.uptimeMillis());
+ } else {
+ Log.d(TAG, "No next node");
+ }
+ }
+
+ /*
+ * If we have a found message, we will get called again so there's no need to set state.
+ * In that case we can leave our state as ACTIVE.
+ *
+ * Otherwise we should determine how to park the thread.
+ */
+ StateNode nextOp = sStackStateActive;
+ if (found == null) {
+ if (next == null) {
+ /* No message to deliver, sleep indefinitely */
+ mNextPollTimeoutMillis = -1;
+ nextOp = sStackStateParked;
+ if (DEBUG) {
+ Log.d(TAG, "nextMessage next state is StackStateParked");
+ }
+ } else {
+ /* Message not ready, or we found one to deliver already, set a timeout */
+ long nextMessageWhen = next.getWhen();
+ if (nextMessageWhen > now) {
+ mNextPollTimeoutMillis = (int) Math.min(nextMessageWhen - now,
+ Integer.MAX_VALUE);
+ } else {
+ mNextPollTimeoutMillis = 0;
+ }
+
+ mStackStateTimedPark.mWhenToWake = now + mNextPollTimeoutMillis;
+ nextOp = mStackStateTimedPark;
+ if (DEBUG) {
+ Log.d(TAG, "nextMessage next state is StackStateTimedParked timeout ms "
+ + mNextPollTimeoutMillis + " mWhenToWake: "
+ + mStackStateTimedPark.mWhenToWake + " now " + now);
+ }
+ }
+ }
+
+ /*
+ * Try to swap our state from Active back to Park or TimedPark. If we raced with
+ * enqueue, loop back around to pick up any new items.
+ */
+ if (sState.compareAndSet(this, sStackStateActive, nextOp)) {
+ mMessageCounts.clearCounts();
+ if (found != null) {
+ if (!removeFromPriorityQueue(found)) {
+ /*
+ * RemoveMessages() might be able to pull messages out from under us
+ * However we can detect that here and just loop around if it happens.
+ */
+ continue;
+ }
+
+ if (TRACE) {
+ Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+ }
+ return found.mMessage;
+ }
+ return null;
+ }
+ }
+ }
+
+ Message next() {
+ final long ptr = mPtr;
+ if (ptr == 0) {
+ return null;
+ }
+
+ mNextPollTimeoutMillis = 0;
+ int pendingIdleHandlerCount = -1; // -1 only during first iteration
+ while (true) {
+ if (mNextPollTimeoutMillis != 0) {
+ Binder.flushPendingCommands();
+ }
+
+ nativePollOnce(ptr, mNextPollTimeoutMillis);
+
+ Message msg = nextMessage();
+ if (msg != null) {
+ msg.markInUse();
+ return msg;
+ }
+
+ if ((boolean) sQuitting.getVolatile(this)) {
+ return null;
+ }
+
+ synchronized (mIdleHandlersLock) {
+ // If first time idle, then get the number of idlers to run.
+ // Idle handles only run if the queue is empty or if the first message
+ // in the queue (possibly a barrier) is due to be handled in the future.
+ if (pendingIdleHandlerCount < 0
+ && mNextPollTimeoutMillis != 0) {
+ pendingIdleHandlerCount = mIdleHandlers.size();
+ }
+ if (pendingIdleHandlerCount <= 0) {
+ // No idle handlers to run. Loop and wait some more.
+ continue;
+ }
+
+ if (mPendingIdleHandlers == null) {
+ mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
+ }
+ mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
+ }
+
+ // Run the idle handlers.
+ // We only ever reach this code block during the first iteration.
+ for (int i = 0; i < pendingIdleHandlerCount; i++) {
+ final IdleHandler idler = mPendingIdleHandlers[i];
+ mPendingIdleHandlers[i] = null; // release the reference to the handler
+
+ boolean keep = false;
+ try {
+ keep = idler.queueIdle();
+ } catch (Throwable t) {
+ Log.wtf(TAG, "IdleHandler threw exception", t);
+ }
+
+ if (!keep) {
+ synchronized (mIdleHandlersLock) {
+ mIdleHandlers.remove(idler);
+ }
+ }
+ }
+
+ // Reset the idle handler count to 0 so we do not run them again.
+ pendingIdleHandlerCount = 0;
+
+ // While calling an idle handler, a new message could have been delivered
+ // so go back and look again for a pending message without waiting.
+ mNextPollTimeoutMillis = 0;
+ }
+ }
+
+ void quit(boolean safe) {
+ if (!mQuitAllowed) {
+ throw new IllegalStateException("Main thread not allowed to quit.");
+ }
+ synchronized (mIdleHandlersLock) {
+ if (sQuitting.compareAndSet(this, false, true)) {
+ if (safe) {
+ removeAllFutureMessages();
+ } else {
+ removeAllMessages();
+ }
+
+ // We can assume mPtr != 0 because sQuitting was previously false.
+ nativeWake(mPtr);
+ }
+ }
+ }
+
+ boolean enqueueMessage(@NonNull Message msg, long when) {
+ if (msg.target == null) {
+ throw new IllegalArgumentException("Message must have a target.");
+ }
+
+ if (msg.isInUse()) {
+ throw new IllegalStateException(msg + " This message is already in use.");
+ }
+
+ return enqueueMessageUnchecked(msg, when);
+ }
+
+ private boolean enqueueMessageUnchecked(@NonNull Message msg, long when) {
+ if ((boolean) sQuitting.getVolatile(this)) {
+ IllegalStateException e = new IllegalStateException(
+ msg.target + " sending message to a Handler on a dead thread");
+ Log.w(TAG, e.getMessage(), e);
+ msg.recycleUnchecked();
+ return false;
+ }
+
+ long seq = when != 0 ? ((long)sNextInsertSeq.getAndAdd(this, 1L) + 1L)
+ : ((long)sNextFrontInsertSeq.getAndAdd(this, -1L) - 1L);
+ /* TODO: Add a MessageNode member to Message so we can avoid this allocation */
+ MessageNode node = new MessageNode(msg, seq);
+ msg.when = when;
+ msg.markInUse();
+
+ if (DEBUG) {
+ Log.d(TAG, "Insert message what: " + msg.what + " when: " + msg.when + " seq: "
+ + node.mInsertSeq + " barrier: " + node.isBarrier() + " async: "
+ + node.isAsync() + " now: " + SystemClock.uptimeMillis());
+ }
+
+ while (true) {
+ StackNode old = (StackNode) sState.getVolatile(this);
+ boolean wakeNeeded;
+ boolean inactive;
+
+ node.mNext = old;
+ switch (old.getNodeType()) {
+ case STACK_NODE_ACTIVE:
+ /*
+ * The worker thread is currently active and will process any elements added to
+ * the stack before parking again.
+ */
+ node.mBottomOfStack = (StateNode) old;
+ inactive = false;
+ node.mWokeUp = true;
+ wakeNeeded = false;
+ break;
+
+ case STACK_NODE_PARKED:
+ node.mBottomOfStack = (StateNode) old;
+ inactive = true;
+ node.mWokeUp = true;
+ wakeNeeded = true;
+ break;
+
+ case STACK_NODE_TIMEDPARK:
+ node.mBottomOfStack = (StateNode) old;
+ inactive = true;
+ wakeNeeded = mStackStateTimedPark.mWhenToWake >= node.getWhen();
+ node.mWokeUp = wakeNeeded;
+ break;
+
+ default:
+ MessageNode oldMessage = (MessageNode) old;
+
+ node.mBottomOfStack = oldMessage.mBottomOfStack;
+ int bottomType = node.mBottomOfStack.getNodeType();
+ inactive = bottomType >= STACK_NODE_PARKED;
+ wakeNeeded = (bottomType == STACK_NODE_TIMEDPARK
+ && mStackStateTimedPark.mWhenToWake >= node.getWhen()
+ && !oldMessage.mWokeUp);
+ node.mWokeUp = oldMessage.mWokeUp || wakeNeeded;
+ break;
+ }
+ if (sState.compareAndSet(this, old, node)) {
+ if (inactive) {
+ if (wakeNeeded) {
+ nativeWake(mPtr);
+ } else {
+ mMessageCounts.incrementQueued();
+ }
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Posts a synchronization barrier to the Looper's message queue.
+ *
+ * Message processing occurs as usual until the message queue encounters the
+ * synchronization barrier that has been posted. When the barrier is encountered,
+ * later synchronous messages in the queue are stalled (prevented from being executed)
+ * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
+ * the token that identifies the synchronization barrier.
+ *
+ * This method is used to immediately postpone execution of all subsequently posted
+ * synchronous messages until a condition is met that releases the barrier.
+ * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
+ * and continue to be processed as usual.
+ *
+ * This call must be always matched by a call to {@link #removeSyncBarrier} with
+ * the same token to ensure that the message queue resumes normal operation.
+ * Otherwise the application will probably hang!
+ *
+ * @return A token that uniquely identifies the barrier. This token must be
+ * passed to {@link #removeSyncBarrier} to release the barrier.
+ *
+ * @hide
+ */
+ @TestApi
+ public int postSyncBarrier() {
+ return postSyncBarrier(SystemClock.uptimeMillis());
+ }
+
+ private int postSyncBarrier(long when) {
+ final int token = mNextBarrierToken.getAndIncrement();
+ final Message msg = Message.obtain();
+
+ msg.markInUse();
+ msg.arg1 = token;
+
+ if (!enqueueMessageUnchecked(msg, when)) {
+ Log.wtf(TAG, "Unexpected error while adding sync barrier!");
+ return -1;
+ }
+
+ return token;
+ }
+
+ private class MatchBarrierToken extends MessageCompare {
+ int mBarrierToken;
+
+ MatchBarrierToken(int token) {
+ super();
+ mBarrierToken = token;
+ }
+
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == null && m.arg1 == mBarrierToken) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Removes a synchronization barrier.
+ *
+ * @param token The synchronization barrier token that was returned by
+ * {@link #postSyncBarrier}.
+ *
+ * @throws IllegalStateException if the barrier was not found.
+ *
+ * @hide
+ */
+ @TestApi
+ public void removeSyncBarrier(int token) {
+ boolean removed;
+ MessageNode first;
+ final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token);
+
+ try {
+ /* Retain the first element to see if we are currently stuck on a barrier. */
+ first = mPriorityQueue.first();
+ } catch (NoSuchElementException e) {
+ /* The queue is empty */
+ first = null;
+ }
+
+ removed = findOrRemoveMessages(null, 0, null, null, 0, matchBarrierToken, true);
+ if (removed && first != null) {
+ Message m = first.mMessage;
+ if (m.target == null && m.arg1 == token) {
+ /* Wake up next() in case it was sleeping on this barrier. */
+ nativeWake(mPtr);
+ }
+ } else if (!removed) {
+ throw new IllegalStateException("The specified message queue synchronization "
+ + " barrier token has not been posted or has already been removed.");
+ }
+ }
+
+ private StateNode getStateNode(StackNode node) {
+ if (node.isMessageNode()) {
+ return ((MessageNode) node).mBottomOfStack;
+ }
+ return (StateNode) node;
+ }
+
+ private void waitForDrainCompleted() {
+ mDrainingLock.lock();
+ while (mNextIsDrainingStack) {
+ mDrainCompleted.awaitUninterruptibly();
+ }
+ mDrainingLock.unlock();
+ }
+
+ /*
+ * This class is used to find matches for hasMessages() and removeMessages()
+ */
+ private abstract static class MessageCompare {
+ public abstract boolean compareMessage(Message m, Handler h, int what, Object object,
+ Runnable r, long when);
+ }
+
+ private boolean stackHasMessages(Handler h, int what, Object object, Runnable r, long when,
+ MessageCompare compare, boolean removeMatches) {
+ boolean found = false;
+ StackNode top = (StackNode) sState.getVolatile(this);
+ StateNode bottom = getStateNode(top);
+
+ /*
+ * If the top node is a state node, there are no reachable messages.
+ * If it's anything other than Active, we can quit as we know that next() is not
+ * consuming items.
+ * If the top node is Active then we know that next() is currently consuming items.
+ * In that case we should wait next() has drained the stack.
+ */
+ if (top == bottom) {
+ if (bottom != sStackStateActive) {
+ return false;
+ }
+ waitForDrainCompleted();
+ return false;
+ }
+
+ /*
+ * We have messages that we may tombstone. Walk the stack until we hit the bottom or we
+ * hit a null pointer.
+ * If we hit the bottom, we are done.
+ * If we hit a null pointer, then the stack is being consumed by next() and we must cycle
+ * until the stack has been drained.
+ */
+ MessageNode p = (MessageNode) top;
+
+ while (true) {
+ if (compare.compareMessage(p.mMessage, h, what, object, r, when)) {
+ found = true;
+ if (DEBUG) {
+ Log.w(TAG, "stackHasMessages node matches");
+ }
+ if (removeMatches) {
+ if (p.removeFromStack()) {
+ p.mMessage.recycleUnchecked();
+ if (mMessageCounts.incrementCancelled()) {
+ nativeWake(mPtr);
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+
+ StackNode n = p.mNext;
+ if (n == null) {
+ /* Next() is walking the stack, we must re-sample */
+ if (DEBUG) {
+ Log.d(TAG, "stackHasMessages next() is walking the stack, we must re-sample");
+ }
+ waitForDrainCompleted();
+ break;
+ }
+ if (!n.isMessageNode()) {
+ /* We reached the end of the stack */
+ return found;
+ }
+ p = (MessageNode) n;
+ }
+
+ return found;
+ }
+
+ private boolean priorityQueueHasMessage(ConcurrentSkipListSet<MessageNode> queue, Handler h,
+ int what, Object object, Runnable r, long when, MessageCompare compare,
+ boolean removeMatches) {
+ Iterator<MessageNode> iterator = queue.iterator();
+ boolean found = false;
+
+ while (iterator.hasNext()) {
+ MessageNode msg = iterator.next();
+
+ if (compare.compareMessage(msg.mMessage, h, what, object, r, when)) {
+ if (removeMatches) {
+ found = true;
+ if (queue.remove(msg)) {
+ msg.mMessage.recycleUnchecked();
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+ return found;
+ }
+
+ private boolean findOrRemoveMessages(Handler h, int what, Object object, Runnable r, long when,
+ MessageCompare compare, boolean removeMatches) {
+ boolean foundInStack, foundInQueue;
+
+ foundInStack = stackHasMessages(h, what, object, r, when, compare, removeMatches);
+ foundInQueue = priorityQueueHasMessage(mPriorityQueue, h, what, object, r, when, compare,
+ removeMatches);
+ foundInQueue |= priorityQueueHasMessage(mAsyncPriorityQueue, h, what, object, r, when,
+ compare, removeMatches);
+
+ return foundInStack || foundInQueue;
+ }
+
+ private static class MatchHandlerWhatAndObject extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.what == what && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerWhatAndObject mMatchHandlerWhatAndObject =
+ new MatchHandlerWhatAndObject();
+ boolean hasMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, false);
+ }
+
+ private static class MatchHandlerWhatAndObjectEquals extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.what == what && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerWhatAndObjectEquals mMatchHandlerWhatAndObjectEquals =
+ new MatchHandlerWhatAndObjectEquals();
+ boolean hasEqualMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals,
+ false);
+ }
+
+ private static class MatchHandlerRunnableAndObject extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.callback == r && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerRunnableAndObject mMatchHandlerRunnableAndObject =
+ new MatchHandlerRunnableAndObject();
+
+ boolean hasMessages(Handler h, Runnable r, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, false);
+ }
+
+ private static class MatchHandler extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandler mMatchHandler = new MatchHandler();
+ boolean hasMessages(Handler h) {
+ if (h == null) {
+ return false;
+ }
+ return findOrRemoveMessages(h, -1, null, null, 0, mMatchHandler, false);
+ }
+
+ void removeMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, true);
+ }
+
+ void removeEqualMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, true);
+ }
+
+ void removeMessages(Handler h, Runnable r, Object object) {
+ if (h == null || r == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true);
+ }
+
+ private static class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.callback == r && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerRunnableAndObjectEquals mMatchHandlerRunnableAndObjectEquals =
+ new MatchHandlerRunnableAndObjectEquals();
+ void removeEqualMessages(Handler h, Runnable r, Object object) {
+ if (h == null || r == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true);
+ }
+
+ private static class MatchHandlerAndObject extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerAndObject mMatchHandlerAndObject = new MatchHandlerAndObject();
+ void removeCallbacksAndMessages(Handler h, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true);
+ }
+
+ private static class MatchHandlerAndObjectEquals extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerAndObjectEquals mMatchHandlerAndObjectEquals =
+ new MatchHandlerAndObjectEquals();
+ void removeCallbacksAndEqualMessages(Handler h, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true);
+ }
+
+ private static class MatchAllMessages extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ return true;
+ }
+ }
+ private final MatchAllMessages mMatchAllMessages = new MatchAllMessages();
+ private void removeAllMessages() {
+ findOrRemoveMessages(null, -1, null, null, 0, mMatchAllMessages, true);
+ }
+
+ private static class MatchAllFutureMessages extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.when > when) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchAllFutureMessages mMatchAllFutureMessages = new MatchAllFutureMessages();
+ private void removeAllFutureMessages() {
+ findOrRemoveMessages(null, -1, null, null, SystemClock.uptimeMillis(),
+ mMatchAllFutureMessages, true);
+ }
+
+ private void printPriorityQueueNodes() {
+ Iterator<MessageNode> iterator = mPriorityQueue.iterator();
+
+ Log.d(TAG, "* Dump priority queue");
+ while (iterator.hasNext()) {
+ MessageNode msgNode = iterator.next();
+ Log.d(TAG, "** MessageNode what: " + msgNode.mMessage.what + " when "
+ + msgNode.mMessage.when + " seq: " + msgNode.mInsertSeq);
+ }
+ }
+
+ private int dumpPriorityQueue(ConcurrentSkipListSet<MessageNode> queue, Printer pw,
+ String prefix, Handler h, int n) {
+ int count = 0;
+ long now = SystemClock.uptimeMillis();
+
+ for (MessageNode msgNode : queue) {
+ Message msg = msgNode.mMessage;
+ if (h == null || h == msg.target) {
+ pw.println(prefix + "Message " + (n + count) + ": " + msg.toString(now));
+ }
+ count++;
+ }
+ return count;
+ }
+
+ void dump(Printer pw, String prefix, Handler h) {
+ long now = SystemClock.uptimeMillis();
+ int n = 0;
+
+ pw.println(prefix + "(MessageQueue is using Concurrent implementation)");
+
+ StackNode node = (StackNode) sState.getVolatile(this);
+ while (node != null) {
+ if (node.isMessageNode()) {
+ Message msg = ((MessageNode) node).mMessage;
+ if (h == null || h == msg.target) {
+ pw.println(prefix + "Message " + n + ": " + msg.toString(now));
+ }
+ node = ((MessageNode) node).mNext;
+ } else {
+ pw.println(prefix + "State: " + node);
+ node = null;
+ }
+ n++;
+ }
+
+ pw.println(prefix + "PriorityQueue Messages: ");
+ n += dumpPriorityQueue(mPriorityQueue, pw, prefix, h, n);
+ pw.println(prefix + "AsyncPriorityQueue Messages: ");
+ n += dumpPriorityQueue(mAsyncPriorityQueue, pw, prefix, h, n);
+
+ pw.println(prefix + "(Total messages: " + n + ", polling=" + isPolling()
+ + ", quitting=" + (boolean) sQuitting.getVolatile(this) + ")");
+ }
+
+ private int dumpPriorityQueue(ConcurrentSkipListSet<MessageNode> queue,
+ ProtoOutputStream proto) {
+ int count = 0;
+
+ for (MessageNode msgNode : queue) {
+ Message msg = msgNode.mMessage;
+ msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+ count++;
+ }
+ return count;
+ }
+
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ final long messageQueueToken = proto.start(fieldId);
+
+ StackNode node = (StackNode) sState.getVolatile(this);
+ while (node.isMessageNode()) {
+ Message msg = ((MessageNode) node).mMessage;
+ msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+ node = ((MessageNode) node).mNext;
+ }
+
+ dumpPriorityQueue(mPriorityQueue, proto);
+ dumpPriorityQueue(mAsyncPriorityQueue, proto);
+
+ proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPolling());
+ proto.write(MessageQueueProto.IS_QUITTING, (boolean) sQuitting.getVolatile(this));
+ proto.end(messageQueueToken);
+ }
+
+ /**
+ * Adds a file descriptor listener to receive notification when file descriptor
+ * related events occur.
+ * <p>
+ * If the file descriptor has already been registered, the specified events
+ * and listener will replace any that were previously associated with it.
+ * It is not possible to set more than one listener per file descriptor.
+ * </p><p>
+ * It is important to always unregister the listener when the file descriptor
+ * is no longer of use.
+ * </p>
+ *
+ * @param fd The file descriptor for which a listener will be registered.
+ * @param events The set of events to receive: a combination of the
+ * {@link OnFileDescriptorEventListener#EVENT_INPUT},
+ * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and
+ * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks. If the requested
+ * set of events is zero, then the listener is unregistered.
+ * @param listener The listener to invoke when file descriptor events occur.
+ *
+ * @see OnFileDescriptorEventListener
+ * @see #removeOnFileDescriptorEventListener
+ */
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
+ @OnFileDescriptorEventListener.Events int events,
+ @NonNull OnFileDescriptorEventListener listener) {
+ if (fd == null) {
+ throw new IllegalArgumentException("fd must not be null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ synchronized (mFileDescriptorRecordsLock) {
+ updateOnFileDescriptorEventListenerLocked(fd, events, listener);
+ }
+ }
+
+ /**
+ * Removes a file descriptor listener.
+ * <p>
+ * This method does nothing if no listener has been registered for the
+ * specified file descriptor.
+ * </p>
+ *
+ * @param fd The file descriptor whose listener will be unregistered.
+ *
+ * @see OnFileDescriptorEventListener
+ * @see #addOnFileDescriptorEventListener
+ */
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
+ if (fd == null) {
+ throw new IllegalArgumentException("fd must not be null");
+ }
+
+ synchronized (mFileDescriptorRecordsLock) {
+ updateOnFileDescriptorEventListenerLocked(fd, 0, null);
+ }
+ }
+
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
+ OnFileDescriptorEventListener listener) {
+ final int fdNum = fd.getInt$();
+
+ int index = -1;
+ FileDescriptorRecord record = null;
+ if (mFileDescriptorRecords != null) {
+ index = mFileDescriptorRecords.indexOfKey(fdNum);
+ if (index >= 0) {
+ record = mFileDescriptorRecords.valueAt(index);
+ if (record != null && record.mEvents == events) {
+ return;
+ }
+ }
+ }
+
+ if (events != 0) {
+ events |= OnFileDescriptorEventListener.EVENT_ERROR;
+ if (record == null) {
+ if (mFileDescriptorRecords == null) {
+ mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();
+ }
+ record = new FileDescriptorRecord(fd, events, listener);
+ mFileDescriptorRecords.put(fdNum, record);
+ } else {
+ record.mListener = listener;
+ record.mEvents = events;
+ record.mSeq += 1;
+ }
+ nativeSetFileDescriptorEvents(mPtr, fdNum, events);
+ } else if (record != null) {
+ record.mEvents = 0;
+ mFileDescriptorRecords.removeAt(index);
+ nativeSetFileDescriptorEvents(mPtr, fdNum, 0);
+ }
+ }
+
+ // Called from native code.
+ private int dispatchEvents(int fd, int events) {
+ // Get the file descriptor record and any state that might change.
+ final FileDescriptorRecord record;
+ final int oldWatchedEvents;
+ final OnFileDescriptorEventListener listener;
+ final int seq;
+ synchronized (mFileDescriptorRecordsLock) {
+ record = mFileDescriptorRecords.get(fd);
+ if (record == null) {
+ return 0; // spurious, no listener registered
+ }
+
+ oldWatchedEvents = record.mEvents;
+ events &= oldWatchedEvents; // filter events based on current watched set
+ if (events == 0) {
+ return oldWatchedEvents; // spurious, watched events changed
+ }
+
+ listener = record.mListener;
+ seq = record.mSeq;
+ }
+
+ // Invoke the listener outside of the lock.
+ int newWatchedEvents = listener.onFileDescriptorEvents(
+ record.mDescriptor, events);
+ if (newWatchedEvents != 0) {
+ newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;
+ }
+
+ // Update the file descriptor record if the listener changed the set of
+ // events to watch and the listener itself hasn't been updated since.
+ if (newWatchedEvents != oldWatchedEvents) {
+ synchronized (mFileDescriptorRecordsLock) {
+ int index = mFileDescriptorRecords.indexOfKey(fd);
+ if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+ && record.mSeq == seq) {
+ record.mEvents = newWatchedEvents;
+ if (newWatchedEvents == 0) {
+ mFileDescriptorRecords.removeAt(index);
+ }
+ }
+ }
+ }
+
+ // Return the new set of events to watch for native code to take care of.
+ return newWatchedEvents;
+ }
+
+ /**
+ * Callback interface for discovering when a thread is going to block
+ * waiting for more messages.
+ */
+ public static interface IdleHandler {
+ /**
+ * Called when the message queue has run out of messages and will now
+ * wait for more. Return true to keep your idle handler active, false
+ * to have it removed. This may be called if there are still messages
+ * pending in the queue, but they are all scheduled to be dispatched
+ * after the current time.
+ */
+ boolean queueIdle();
+ }
+
+ /**
+ * A listener which is invoked when file descriptor related events occur.
+ */
+ public interface OnFileDescriptorEventListener {
+ /**
+ * File descriptor event: Indicates that the file descriptor is ready for input
+ * operations, such as reading.
+ * <p>
+ * The listener should read all available data from the file descriptor
+ * then return <code>true</code> to keep the listener active or <code>false</code>
+ * to remove the listener.
+ * </p><p>
+ * In the case of a socket, this event may be generated to indicate
+ * that there is at least one incoming connection that the listener
+ * should accept.
+ * </p><p>
+ * This event will only be generated if the {@link #EVENT_INPUT} event mask was
+ * specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_INPUT = 1 << 0;
+
+ /**
+ * File descriptor event: Indicates that the file descriptor is ready for output
+ * operations, such as writing.
+ * <p>
+ * The listener should write as much data as it needs. If it could not
+ * write everything at once, then it should return <code>true</code> to
+ * keep the listener active. Otherwise, it should return <code>false</code>
+ * to remove the listener then re-register it later when it needs to write
+ * something else.
+ * </p><p>
+ * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was
+ * specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_OUTPUT = 1 << 1;
+
+ /**
+ * File descriptor event: Indicates that the file descriptor encountered a
+ * fatal error.
+ * <p>
+ * File descriptor errors can occur for various reasons. One common error
+ * is when the remote peer of a socket or pipe closes its end of the connection.
+ * </p><p>
+ * This event may be generated at any time regardless of whether the
+ * {@link #EVENT_ERROR} event mask was specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_ERROR = 1 << 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = { "EVENT_" }, value = {
+ EVENT_INPUT,
+ EVENT_OUTPUT,
+ EVENT_ERROR
+ })
+ public @interface Events {}
+
+ /**
+ * Called when a file descriptor receives events.
+ *
+ * @param fd The file descriptor.
+ * @param events The set of events that occurred: a combination of the
+ * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks.
+ * @return The new set of events to watch, or 0 to unregister the listener.
+ *
+ * @see #EVENT_INPUT
+ * @see #EVENT_OUTPUT
+ * @see #EVENT_ERROR
+ */
+ @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events);
+ }
+
+ static final class FileDescriptorRecord {
+ public final FileDescriptor mDescriptor;
+ public int mEvents;
+ public OnFileDescriptorEventListener mListener;
+ public int mSeq;
+
+ public FileDescriptorRecord(FileDescriptor descriptor,
+ int events, OnFileDescriptorEventListener listener) {
+ mDescriptor = descriptor;
+ mEvents = events;
+ mListener = listener;
+ }
+ }
+}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index a459aaa..2c7b9c0 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -159,6 +159,8 @@
@UnsupportedAppUsage
private static UserEnvironment sCurrentUser;
private static boolean sUserRequired;
+ private static Boolean sLegacyStorageAppOp;
+ private static Boolean sNoIsolatedStorageAppOp;
static {
initForCurrentUser();
@@ -1459,15 +1461,23 @@
final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
final String opPackageName = context.getOpPackageName();
- if (appOps.noteOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid,
- opPackageName) == AppOpsManager.MODE_ALLOWED) {
- return true;
+ if (sLegacyStorageAppOp == null) {
+ sLegacyStorageAppOp =
+ appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, opPackageName) ==
+ AppOpsManager.MODE_ALLOWED;
+ }
+ if (sLegacyStorageAppOp) {
+ return sLegacyStorageAppOp;
}
// Legacy external storage access is granted to instrumentations invoked with
// "--no-isolated-storage" flag.
- return appOps.noteOpNoThrow(AppOpsManager.OP_NO_ISOLATED_STORAGE, uid,
- opPackageName) == AppOpsManager.MODE_ALLOWED;
+ if (sNoIsolatedStorageAppOp == null) {
+ sNoIsolatedStorageAppOp =
+ appOps.checkOpNoThrow(AppOpsManager.OP_NO_ISOLATED_STORAGE, uid,
+ opPackageName) == AppOpsManager.MODE_ALLOWED;
+ }
+ return sNoIsolatedStorageAppOp;
}
private static boolean isScopedStorageEnforced(boolean defaultScopedStorage,
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
similarity index 97%
rename from core/java/android/os/MessageQueue.java
rename to core/java/android/os/LegacyMessageQueue/MessageQueue.java
index 5b711c9..6b9b349 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
@@ -20,6 +20,9 @@
import android.annotation.NonNull;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Handler;
+import android.os.Process;
+import android.os.Trace;
import android.util.Log;
import android.util.Printer;
import android.util.SparseArray;
@@ -29,6 +32,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicLong;
/**
* Low-level class holding the list of messages to be dispatched by a
@@ -44,6 +48,7 @@
public final class MessageQueue {
private static final String TAG = "MessageQueue";
private static final boolean DEBUG = false;
+ private static final boolean TRACE = false;
// True if the message queue can be quit.
@UnsupportedAppUsage
@@ -326,6 +331,8 @@
return newWatchedEvents;
}
+ private static final AtomicLong mMessagesDelivered = new AtomicLong();
+
@UnsupportedAppUsage
Message next() {
// Return here if the message loop has already quit and been disposed.
@@ -381,6 +388,9 @@
if (msg.isAsynchronous()) {
mAsyncMessageCount--;
}
+ if (TRACE) {
+ Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+ }
return msg;
}
} else {
@@ -794,7 +804,7 @@
Message n = p.next;
if (n != null) {
if (n.target == h && n.what == what
- && (object == null || n.obj == object)) {
+ && (object == null || n.obj == object)) {
Message nn = n.next;
if (n.isAsynchronous()) {
mAsyncMessageCount--;
@@ -841,7 +851,7 @@
Message n = p.next;
if (n != null) {
if (n.target == h && n.what == what
- && (object == null || object.equals(n.obj))) {
+ && (object == null || object.equals(n.obj))) {
Message nn = n.next;
if (n.isAsynchronous()) {
mAsyncMessageCount--;
@@ -888,7 +898,7 @@
Message n = p.next;
if (n != null) {
if (n.target == h && n.callback == r
- && (object == null || n.obj == object)) {
+ && (object == null || n.obj == object)) {
Message nn = n.next;
if (n.isAsynchronous()) {
mAsyncMessageCount--;
@@ -935,7 +945,7 @@
Message n = p.next;
if (n != null) {
if (n.target == h && n.callback == r
- && (object == null || object.equals(n.obj))) {
+ && (object == null || object.equals(n.obj))) {
Message nn = n.next;
if (n.isAsynchronous()) {
mAsyncMessageCount--;
@@ -1093,6 +1103,7 @@
void dump(Printer pw, String prefix, Handler h) {
synchronized (this) {
+ pw.println(prefix + "(MessageQueue is using Legacy implementation)");
long now = SystemClock.uptimeMillis();
int n = 0;
for (Message msg = mMessages; msg != null; msg = msg.next) {
diff --git a/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
new file mode 100644
index 0000000..967332f
--- /dev/null
+++ b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
@@ -0,0 +1,1589 @@
+/*
+ * Copyright (C) 2024 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 android.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Handler;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Printer;
+import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.PriorityQueue;
+import java.util.PriorityQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Low-level class holding the list of messages to be dispatched by a
+ * {@link Looper}. Messages are not added directly to a MessageQueue,
+ * but rather through {@link Handler} objects associated with the Looper.
+ *
+ * <p>You can retrieve the MessageQueue for the current thread with
+ * {@link Looper#myQueue() Looper.myQueue()}.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
+ "com.android.platform.test.ravenwood.nativesubstitution.MessageQueue_host")
+public final class MessageQueue {
+ private static final String TAG = "SemiConcurrentMessageQueue";
+ private static final boolean DEBUG = false;
+ private static final boolean TRACE = false;
+
+ // True if the message queue can be quit.
+ private final boolean mQuitAllowed;
+
+ @SuppressWarnings("unused")
+ private long mPtr; // used by native code
+
+ @IntDef(value = {
+ STACK_NODE_MESSAGE,
+ STACK_NODE_ACTIVE,
+ STACK_NODE_PARKED,
+ STACK_NODE_TIMEDPARK})
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface StackNodeType {}
+
+ /*
+ * Stack node types. STACK_NODE_MESSAGE indicates a node containing a message.
+ * The other types indicate what state our Looper thread is in. The bottom of
+ * the stack is always a single state node. Message nodes are added on top.
+ */
+ private static final int STACK_NODE_MESSAGE = 0;
+ /*
+ * Active state indicates that next() is processing messages
+ */
+ private static final int STACK_NODE_ACTIVE = 1;
+ /*
+ * Parked state indicates that the Looper thread is sleeping indefinitely (nothing to deliver)
+ */
+ private static final int STACK_NODE_PARKED = 2;
+ /*
+ * Timed Park state indicates that the Looper thread is sleeping, waiting for a message
+ * deadline
+ */
+ private static final int STACK_NODE_TIMEDPARK = 3;
+
+ /* Describes a node in the Treiber stack */
+ static class StackNode {
+ @StackNodeType
+ private final int mType;
+
+ StackNode(@StackNodeType int type) {
+ mType = type;
+ }
+
+ @StackNodeType
+ final int getNodeType() {
+ return mType;
+ }
+
+ final boolean isMessageNode() {
+ return mType == STACK_NODE_MESSAGE;
+ }
+ }
+
+ static final class MessageNode extends StackNode implements Comparable<MessageNode> {
+ private final Message mMessage;
+ volatile StackNode mNext;
+ StateNode mBottomOfStack;
+ boolean mWokeUp;
+ boolean mRemovedFromStack = false;
+ final long mInsertSeq;
+
+ MessageNode(@NonNull Message message, long insertSeq) {
+ super(STACK_NODE_MESSAGE);
+ mMessage = message;
+ mInsertSeq = insertSeq;
+ }
+
+ long getWhen() {
+ return mMessage.when;
+ }
+
+ boolean isRemovedFromStack() {
+ return mRemovedFromStack;
+ }
+
+ boolean removeFromStack() {
+ if (!mRemovedFromStack) {
+ mRemovedFromStack = true;
+ return true;
+ }
+ return false;
+ }
+
+ boolean isAsync() {
+ return mMessage.isAsynchronous();
+ }
+
+ boolean isBarrier() {
+ return mMessage.target == null;
+ }
+
+ @Override
+ public int compareTo(@NonNull MessageNode messageNode) {
+ Message other = messageNode.mMessage;
+
+ int compared = Long.compare(mMessage.when, other.when);
+ if (compared == 0) {
+ compared = Long.compare(mInsertSeq, messageNode.mInsertSeq);
+ }
+ return compared;
+ }
+ }
+
+ static class StateNode extends StackNode {
+ StateNode(int type) {
+ super(type);
+ }
+ }
+
+ static final class TimedParkStateNode extends StateNode {
+ long mWhenToWake;
+
+ TimedParkStateNode() {
+ super(STACK_NODE_TIMEDPARK);
+ }
+ }
+
+ private static final StateNode sStackStateActive = new StateNode(STACK_NODE_ACTIVE);
+ private static final StateNode sStackStateParked = new StateNode(STACK_NODE_PARKED);
+ private final TimedParkStateNode mStackStateTimedPark = new TimedParkStateNode();
+
+ /* This is the top of our treiber stack. */
+ private static final VarHandle sState;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sState = l.findVarHandle(MessageQueue.class, "mStateValue",
+ MessageQueue.StackNode.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ private volatile StackNode mStateValue = sStackStateParked;
+ @GuardedBy("mPriorityQueue")
+ private final PriorityQueue<MessageNode> mPriorityQueue =
+ new PriorityQueue<MessageNode>();
+ @GuardedBy("mPriorityQueue")
+ private final PriorityQueue<MessageNode> mAsyncPriorityQueue =
+ new PriorityQueue<MessageNode>();
+
+ /*
+ * This helps us ensure that messages with the same timestamp are inserted in FIFO order.
+ * Increments on each insert, starting at 0. MessageNode.compareTo() will compare sequences
+ * when delivery timestamps are identical.
+ */
+ private static final VarHandle sNextInsertSeq;
+ private volatile long mNextInsertSeqValue = 0;
+ /*
+ * The exception to the FIFO order rule is sendMessageAtFrontOfQueue().
+ * Those messages must be in LIFO order - SIGH.
+ * Decrements on each front of queue insert.
+ */
+ private static final VarHandle sNextFrontInsertSeq;
+ private volatile long mNextFrontInsertSeqValue = -1;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sNextInsertSeq = l.findVarHandle(MessageQueue.class, "mNextInsertSeqValue",
+ long.class);
+ sNextFrontInsertSeq = l.findVarHandle(MessageQueue.class, "mNextFrontInsertSeqValue",
+ long.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+
+ }
+
+ /*
+ * Tracks the number of queued and cancelled messages in our stack.
+ *
+ * On item cancellation, determine whether to wake next() to flush tombstoned messages.
+ * We track queued and cancelled counts as two ints packed into a single long.
+ */
+ private static final class MessageCounts {
+ private static VarHandle sCounts;
+ private volatile long mCountsValue = 0;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sCounts = l.findVarHandle(MessageQueue.MessageCounts.class, "mCountsValue",
+ long.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+ /* We use a special value to indicate when next() has been woken for flush. */
+ private static final long AWAKE = Long.MAX_VALUE;
+ /*
+ * Minimum number of messages in the stack which we need before we consider flushing
+ * tombstoned items.
+ */
+ private static final int MESSAGE_FLUSH_THRESHOLD = 10;
+
+ private static int numQueued(long val) {
+ return (int) (val >>> Integer.SIZE);
+ }
+
+ private static int numCancelled(long val) {
+ return (int) val;
+ }
+
+ private static long combineCounts(int queued, int cancelled) {
+ return ((long) queued << Integer.SIZE) | (long) cancelled;
+ }
+
+ public void incrementQueued() {
+ while (true) {
+ long oldVal = mCountsValue;
+ int queued = numQueued(oldVal);
+ int cancelled = numCancelled(oldVal);
+ /* Use Math.max() to avoid overflow of queued count */
+ long newVal = combineCounts(Math.max(queued + 1, queued), cancelled);
+
+ /* Don't overwrite 'AWAKE' state */
+ if (oldVal == AWAKE || sCounts.compareAndSet(this, oldVal, newVal)) {
+ break;
+ }
+ }
+ }
+
+ public boolean incrementCancelled() {
+ while (true) {
+ long oldVal = mCountsValue;
+ if (oldVal == AWAKE) {
+ return false;
+ }
+ int queued = numQueued(oldVal);
+ int cancelled = numCancelled(oldVal);
+ boolean needsPurge = queued > MESSAGE_FLUSH_THRESHOLD
+ && (queued >> 1) < cancelled;
+ long newVal;
+ if (needsPurge) {
+ newVal = AWAKE;
+ } else {
+ newVal = combineCounts(queued,
+ Math.max(cancelled + 1, cancelled));
+ }
+
+ if (sCounts.compareAndSet(this, oldVal, newVal)) {
+ return needsPurge;
+ }
+ }
+ }
+
+ public void clearCounts() {
+ mCountsValue = 0;
+ }
+ }
+
+ private final MessageCounts mMessageCounts = new MessageCounts();
+
+ private final Object mIdleHandlersLock = new Object();
+ @GuardedBy("mIdleHandlersLock")
+ private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
+ private IdleHandler[] mPendingIdleHandlers;
+
+ private final Object mFileDescriptorRecordsLock = new Object();
+ @GuardedBy("mFileDescriptorRecordsLock")
+ private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
+
+ private static final VarHandle sQuitting;
+ private boolean mQuittingValue = false;
+ static {
+ try {
+ MethodHandles.Lookup l = MethodHandles.lookup();
+ sQuitting = l.findVarHandle(MessageQueue.class, "mQuittingValue", boolean.class);
+ } catch (Exception e) {
+ Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ // The next barrier token.
+ // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+ private final AtomicInteger mNextBarrierToken = new AtomicInteger(1);
+
+ private static native long nativeInit();
+ private static native void nativeDestroy(long ptr);
+ private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
+ private static native void nativeWake(long ptr);
+ private static native boolean nativeIsPolling(long ptr);
+ private static native void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
+
+ MessageQueue(boolean quitAllowed) {
+ mQuitAllowed = quitAllowed;
+ mPtr = nativeInit();
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ dispose();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ // Disposes of the underlying message queue.
+ // Must only be called on the looper thread or the finalizer.
+ private void dispose() {
+ if (mPtr != 0) {
+ nativeDestroy(mPtr);
+ mPtr = 0;
+ }
+ }
+
+ /**
+ * Returns true if the looper has no pending messages which are due to be processed.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @return True if the looper is idle.
+ */
+ public boolean isIdle() {
+ MessageNode msgNode = null;
+ MessageNode asyncMsgNode = null;
+
+ synchronized (mPriorityQueue) {
+ msgNode = mPriorityQueue.peek();
+ asyncMsgNode = mAsyncPriorityQueue.peek();
+
+ final long now = SystemClock.uptimeMillis();
+ if ((msgNode != null && msgNode.getWhen() <= now)
+ || (asyncMsgNode != null && asyncMsgNode.getWhen() <= now)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Add a new {@link IdleHandler} to this message queue. This may be
+ * removed automatically for you by returning false from
+ * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
+ * invoked, or explicitly removing it with {@link #removeIdleHandler}.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @param handler The IdleHandler to be added.
+ */
+ public void addIdleHandler(@NonNull IdleHandler handler) {
+ if (handler == null) {
+ throw new NullPointerException("Can't add a null IdleHandler");
+ }
+ synchronized (mIdleHandlersLock) {
+ mIdleHandlers.add(handler);
+ }
+ }
+
+ /**
+ * Remove an {@link IdleHandler} from the queue that was previously added
+ * with {@link #addIdleHandler}. If the given object is not currently
+ * in the idle list, nothing is done.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @param handler The IdleHandler to be removed.
+ */
+ public void removeIdleHandler(@NonNull IdleHandler handler) {
+ synchronized (mIdleHandlersLock) {
+ mIdleHandlers.remove(handler);
+ }
+ }
+
+ /**
+ * Returns whether this looper's thread is currently polling for more work to do.
+ * This is a good signal that the loop is still alive rather than being stuck
+ * handling a callback. Note that this method is intrinsically racy, since the
+ * state of the loop can change before you get the result back.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @return True if the looper is currently polling for events.
+ * @hide
+ */
+ public boolean isPolling() {
+ // If the loop is quitting then it must not be idling.
+ // We can assume mPtr != 0 when sQuitting is false.
+ return !((boolean) sQuitting.getVolatile(this)) && nativeIsPolling(mPtr);
+ }
+
+ /* Helper to choose the correct queue to insert into. */
+ @GuardedBy("mPriorityQueue")
+ private void insertIntoPriorityQueue(MessageNode msgNode) {
+ if (msgNode.isAsync()) {
+ mAsyncPriorityQueue.offer(msgNode);
+ } else {
+ mPriorityQueue.offer(msgNode);
+ }
+ }
+
+ @GuardedBy("mPriorityQueue")
+ private boolean removeFromPriorityQueue(MessageNode msgNode) {
+ if (msgNode.isAsync()) {
+ return mAsyncPriorityQueue.remove(msgNode);
+ } else {
+ return mPriorityQueue.remove(msgNode);
+ }
+ }
+
+ private MessageNode pickEarliestNode(MessageNode nodeA, MessageNode nodeB) {
+ if (nodeA != null && nodeB != null) {
+ if (nodeA.compareTo(nodeB) < 0) {
+ return nodeA;
+ }
+ return nodeB;
+ }
+
+ return nodeA != null ? nodeA : nodeB;
+ }
+
+ /* Move any non-cancelled messages into the priority queue */
+ private void drainStack(StackNode oldTop) {
+ while (oldTop.isMessageNode()) {
+ MessageNode oldTopMessageNode = (MessageNode) oldTop;
+ if (oldTopMessageNode.removeFromStack()) {
+ insertIntoPriorityQueue(oldTopMessageNode);
+ }
+ MessageNode inserted = oldTopMessageNode;
+ oldTop = oldTopMessageNode.mNext;
+ }
+ }
+
+ /* Set the stack state to Active, return a list of nodes to walk. */
+ private StackNode swapAndSetStackStateActive() {
+ while (true) {
+ /* Set stack state to Active, get node list to walk later */
+ StackNode current = (StackNode) sState.getVolatile(this);
+ if (current == sStackStateActive
+ || sState.compareAndSet(this, current, sStackStateActive)) {
+ return current;
+ }
+ }
+ }
+
+ /* This is only read/written from the Looper thread */
+ private int mNextPollTimeoutMillis;
+ private static final AtomicLong mMessagesDelivered = new AtomicLong();
+
+ private Message nextMessage() {
+ int i = 0;
+
+ while (true) {
+ if (DEBUG) {
+ Log.d(TAG, "nextMessage loop #" + i);
+ i++;
+ }
+
+ /* This protects us from racing with remove. Enqueue can still add items. */
+ synchronized (mPriorityQueue) {
+
+ /*
+ * Set our state to active, drain any items from the stack into our priority queues
+ */
+ StackNode oldTop;
+ oldTop = swapAndSetStackStateActive();
+ drainStack(oldTop);
+
+ /*
+ * The objective of this next block of code is to:
+ * - find a message to return (if any is ready)
+ * - find a next message we would like to return, after scheduling.
+ * - we make our scheduling decision based on this next message (if it exists).
+ *
+ * We have two queues to juggle and the presence of barriers throws an additional
+ * wrench into our plans.
+ */
+
+ /* Get the first node from each queue */
+ MessageNode msgNode = mPriorityQueue.peek();
+ MessageNode asyncMsgNode = mAsyncPriorityQueue.peek();
+
+ if (DEBUG) {
+ if (msgNode != null) {
+ Message msg = msgNode.mMessage;
+ Log.d(TAG, "Next found node what: " + msg.what + " when: " + msg.when
+ + " seq: " + msgNode.mInsertSeq + "barrier: "
+ + msgNode.isBarrier() + " now: "
+ + SystemClock.uptimeMillis());
+ }
+ if (asyncMsgNode != null) {
+ Message msg = asyncMsgNode.mMessage;
+ Log.d(TAG, "Next found async node what: " + msg.what + " when: " + msg.when
+ + " seq: " + asyncMsgNode.mInsertSeq + "barrier: "
+ + asyncMsgNode.isBarrier() + " now: "
+ + SystemClock.uptimeMillis());
+ }
+ }
+
+ /*
+ * the node which we will return, null if none are ready
+ */
+ MessageNode found = null;
+ /*
+ * The node from which we will determine our next wakeup time.
+ * Null indicates there is no next message ready. If we found a node,
+ * we can leave this null as Looper will call us again after delivering
+ * the message.
+ */
+ MessageNode next = null;
+
+ long now = SystemClock.uptimeMillis();
+ /*
+ * If we have a barrier we should return the async node if it exists and is
+ * ready
+ */
+ if (msgNode != null && msgNode.isBarrier()) {
+ if (asyncMsgNode != null && now >= asyncMsgNode.getWhen()) {
+ found = asyncMsgNode;
+ removeFromPriorityQueue(found);
+ } else {
+ next = asyncMsgNode;
+ }
+ } else { /* No barrier. */
+ MessageNode earliest;
+ /*
+ * If we have two messages, pick the earliest option from either queue.
+ * Otherwise grab whichever node is non-null. If both are null we'll fall
+ * through.
+ */
+ earliest = pickEarliestNode(msgNode, asyncMsgNode);
+
+ if (earliest != null) {
+ if (now >= earliest.getWhen()) {
+ found = earliest;
+ removeFromPriorityQueue(found);
+ } else {
+ next = earliest;
+ }
+ }
+ }
+
+ if (DEBUG) {
+ if (found != null) {
+ Message msg = found.mMessage;
+ Log.d(TAG, "Will deliver node what: " + msg.what + " when: " + msg.when
+ + " seq: " + found.mInsertSeq + " barrier: "
+ + found.isBarrier() + " async: " + found.isAsync()
+ + " now: " + SystemClock.uptimeMillis());
+ } else {
+ Log.d(TAG, "No node to deliver");
+ }
+ if (next != null) {
+ Message msg = next.mMessage;
+ Log.d(TAG, "Next node what: " + msg.what + " when: " + msg.when + " seq: "
+ + next.mInsertSeq + " barrier: " + next.isBarrier()
+ + " async: " + next.isAsync()
+ + " now: " + SystemClock.uptimeMillis());
+ } else {
+ Log.d(TAG, "No next node");
+ }
+ }
+
+ /*
+ * If we have a found message, we will get called again so there's no need to set
+ * state.
+ * In that case we can leave our state as ACTIVE.
+ *
+ * Otherwise we should determine how to park the thread.
+ */
+ StateNode nextOp = sStackStateActive;
+ if (found == null) {
+ if (next == null) {
+ /* No message to deliver, sleep indefinitely */
+ mNextPollTimeoutMillis = -1;
+ nextOp = sStackStateParked;
+ if (DEBUG) {
+ Log.d(TAG, "nextMessage next state is StackStateParked");
+ }
+ } else {
+ /* Message not ready, or we found one to deliver already, set a timeout */
+ long nextMessageWhen = next.getWhen();
+ if (nextMessageWhen > now) {
+ mNextPollTimeoutMillis = (int) Math.min(nextMessageWhen - now,
+ Integer.MAX_VALUE);
+ } else {
+ mNextPollTimeoutMillis = 0;
+ }
+
+ mStackStateTimedPark.mWhenToWake = now + mNextPollTimeoutMillis;
+ nextOp = mStackStateTimedPark;
+ if (DEBUG) {
+ Log.d(TAG, "nextMessage next state is StackStateTimedParked "
+ + " next timeout ms " + mNextPollTimeoutMillis
+ + " mWhenToWake: " + mStackStateTimedPark.mWhenToWake
+ + " now " + now);
+ }
+ }
+ }
+
+ /*
+ * Try to swap our state from Active back to Park or TimedPark. If we raced with
+ * enqueue, loop back around to pick up any new items.
+ */
+ if (sState.compareAndSet(this, sStackStateActive, nextOp)) {
+ mMessageCounts.clearCounts();
+ if (found != null) {
+ if (TRACE) {
+ Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+ }
+ return found.mMessage;
+ }
+ return null;
+ }
+ if (found != null) {
+ /*
+ * Add this node back - we will be adding new nodes into our priority queue, and
+ * recalculating what to return.
+ */
+ insertIntoPriorityQueue(found);
+ }
+ }
+ }
+ }
+
+ Message next() {
+ final long ptr = mPtr;
+ if (ptr == 0) {
+ return null;
+ }
+
+ mNextPollTimeoutMillis = 0;
+ int pendingIdleHandlerCount = -1; // -1 only during first iteration
+ while (true) {
+ if (mNextPollTimeoutMillis != 0) {
+ Binder.flushPendingCommands();
+ }
+
+ nativePollOnce(ptr, mNextPollTimeoutMillis);
+
+ Message msg = nextMessage();
+ if (msg != null) {
+ msg.markInUse();
+ return msg;
+ }
+
+ if ((boolean) sQuitting.getVolatile(this)) {
+ return null;
+ }
+
+ synchronized (mIdleHandlersLock) {
+ // If first time idle, then get the number of idlers to run.
+ // Idle handles only run if the queue is empty or if the first message
+ // in the queue (possibly a barrier) is due to be handled in the future.
+ if (pendingIdleHandlerCount < 0
+ && mNextPollTimeoutMillis != 0) {
+ pendingIdleHandlerCount = mIdleHandlers.size();
+ }
+ if (pendingIdleHandlerCount <= 0) {
+ // No idle handlers to run. Loop and wait some more.
+ continue;
+ }
+
+ if (mPendingIdleHandlers == null) {
+ mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
+ }
+ mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
+ }
+
+ // Run the idle handlers.
+ // We only ever reach this code block during the first iteration.
+ for (int i = 0; i < pendingIdleHandlerCount; i++) {
+ final IdleHandler idler = mPendingIdleHandlers[i];
+ mPendingIdleHandlers[i] = null; // release the reference to the handler
+
+ boolean keep = false;
+ try {
+ keep = idler.queueIdle();
+ } catch (Throwable t) {
+ Log.wtf(TAG, "IdleHandler threw exception", t);
+ }
+
+ if (!keep) {
+ synchronized (mIdleHandlersLock) {
+ mIdleHandlers.remove(idler);
+ }
+ }
+ }
+
+ // Reset the idle handler count to 0 so we do not run them again.
+ pendingIdleHandlerCount = 0;
+
+ // While calling an idle handler, a new message could have been delivered
+ // so go back and look again for a pending message without waiting.
+ mNextPollTimeoutMillis = 0;
+ }
+ }
+
+ void quit(boolean safe) {
+ if (!mQuitAllowed) {
+ throw new IllegalStateException("Main thread not allowed to quit.");
+ }
+ synchronized (mIdleHandlersLock) {
+ if (sQuitting.compareAndSet(this, false, true)) {
+ if (safe) {
+ removeAllFutureMessages();
+ } else {
+ removeAllMessages();
+ }
+
+ // We can assume mPtr != 0 because sQuitting was previously false.
+ nativeWake(mPtr);
+ }
+ }
+ }
+
+ boolean enqueueMessage(@NonNull Message msg, long when) {
+ if (msg.target == null) {
+ throw new IllegalArgumentException("Message must have a target.");
+ }
+
+ if (msg.isInUse()) {
+ throw new IllegalStateException(msg + " This message is already in use.");
+ }
+
+ return enqueueMessageUnchecked(msg, when);
+ }
+
+ private boolean enqueueMessageUnchecked(@NonNull Message msg, long when) {
+ if ((boolean) sQuitting.getVolatile(this)) {
+ IllegalStateException e = new IllegalStateException(
+ msg.target + " sending message to a Handler on a dead thread");
+ Log.w(TAG, e.getMessage(), e);
+ msg.recycleUnchecked();
+ return false;
+ }
+
+ long seq = when != 0 ? ((long)sNextInsertSeq.getAndAdd(this, 1L) + 1L)
+ : ((long)sNextFrontInsertSeq.getAndAdd(this, -1L) - 1L);
+ /* TODO: Add a MessageNode member to Message so we can avoid this allocation */
+ MessageNode node = new MessageNode(msg, seq);
+ msg.when = when;
+ msg.markInUse();
+
+ if (DEBUG) {
+ Log.d(TAG, "Insert message what: " + msg.what + " when: " + msg.when + " seq: "
+ + node.mInsertSeq + " barrier: " + node.isBarrier() + " async: "
+ + node.isAsync() + " now: " + SystemClock.uptimeMillis());
+ }
+
+ while (true) {
+ StackNode old = (StackNode) sState.getVolatile(this);
+ boolean wakeNeeded;
+ boolean inactive;
+
+ node.mNext = old;
+ switch (old.getNodeType()) {
+ case STACK_NODE_ACTIVE:
+ /*
+ * The worker thread is currently active and will process any elements added to
+ * the stack before parking again.
+ */
+ node.mBottomOfStack = (StateNode) old;
+ inactive = false;
+ node.mWokeUp = true;
+ wakeNeeded = false;
+ break;
+
+ case STACK_NODE_PARKED:
+ node.mBottomOfStack = (StateNode) old;
+ inactive = true;
+ node.mWokeUp = true;
+ wakeNeeded = true;
+ break;
+
+ case STACK_NODE_TIMEDPARK:
+ node.mBottomOfStack = (StateNode) old;
+ inactive = true;
+ wakeNeeded = mStackStateTimedPark.mWhenToWake >= node.getWhen();
+ node.mWokeUp = wakeNeeded;
+ break;
+
+ default:
+ MessageNode oldMessage = (MessageNode) old;
+
+ node.mBottomOfStack = oldMessage.mBottomOfStack;
+ int bottomType = node.mBottomOfStack.getNodeType();
+ inactive = bottomType >= STACK_NODE_PARKED;
+ wakeNeeded = (bottomType == STACK_NODE_TIMEDPARK
+ && mStackStateTimedPark.mWhenToWake >= node.getWhen()
+ && !oldMessage.mWokeUp);
+ node.mWokeUp = oldMessage.mWokeUp || wakeNeeded;
+ break;
+ }
+ if (sState.compareAndSet(this, old, node)) {
+ if (inactive) {
+ if (wakeNeeded) {
+ nativeWake(mPtr);
+ } else {
+ mMessageCounts.incrementQueued();
+ }
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Posts a synchronization barrier to the Looper's message queue.
+ *
+ * Message processing occurs as usual until the message queue encounters the
+ * synchronization barrier that has been posted. When the barrier is encountered,
+ * later synchronous messages in the queue are stalled (prevented from being executed)
+ * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
+ * the token that identifies the synchronization barrier.
+ *
+ * This method is used to immediately postpone execution of all subsequently posted
+ * synchronous messages until a condition is met that releases the barrier.
+ * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
+ * and continue to be processed as usual.
+ *
+ * This call must be always matched by a call to {@link #removeSyncBarrier} with
+ * the same token to ensure that the message queue resumes normal operation.
+ * Otherwise the application will probably hang!
+ *
+ * @return A token that uniquely identifies the barrier. This token must be
+ * passed to {@link #removeSyncBarrier} to release the barrier.
+ *
+ * @hide
+ */
+ @TestApi
+ public int postSyncBarrier() {
+ return postSyncBarrier(SystemClock.uptimeMillis());
+ }
+
+ private int postSyncBarrier(long when) {
+ final int token = mNextBarrierToken.getAndIncrement();
+ final Message msg = Message.obtain();
+
+ msg.markInUse();
+ msg.arg1 = token;
+
+ if (!enqueueMessageUnchecked(msg, when)) {
+ Log.wtf(TAG, "Unexpected error while adding sync barrier!");
+ return -1;
+ }
+
+ return token;
+ }
+
+ private class MatchBarrierToken extends MessageCompare {
+ int mBarrierToken;
+
+ MatchBarrierToken(int token) {
+ super();
+ mBarrierToken = token;
+ }
+
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == null && m.arg1 == mBarrierToken) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Removes a synchronization barrier.
+ *
+ * @param token The synchronization barrier token that was returned by
+ * {@link #postSyncBarrier}.
+ *
+ * @throws IllegalStateException if the barrier was not found.
+ *
+ * @hide
+ */
+ @TestApi
+ public void removeSyncBarrier(int token) {
+ boolean removed;
+ MessageNode first;
+ final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token);
+
+ synchronized (mPriorityQueue) {
+ try {
+ /* Retain the first element to see if we are currently stuck on a barrier. */
+ first = mPriorityQueue.peek();
+ } catch (NoSuchElementException e) {
+ /* The queue is empty */
+ first = null;
+ }
+
+ removed = findOrRemoveMessages(null, 0, null, null, 0, matchBarrierToken, true);
+ if (removed && first != null) {
+ Message m = first.mMessage;
+ if (m.target == null && m.arg1 == token) {
+ /* Wake up next() in case it was sleeping on this barrier. */
+ nativeWake(mPtr);
+ }
+ } else if (!removed) {
+ throw new IllegalStateException("The specified message queue synchronization "
+ + " barrier token has not been posted or has already been removed.");
+ }
+ }
+ }
+
+ private StateNode getStateNode(StackNode node) {
+ if (node.isMessageNode()) {
+ return ((MessageNode) node).mBottomOfStack;
+ }
+ return (StateNode) node;
+ }
+
+ /*
+ * This class is used to find matches for hasMessages() and removeMessages()
+ */
+ private abstract static class MessageCompare {
+ public abstract boolean compareMessage(Message m, Handler h, int what, Object object,
+ Runnable r, long when);
+ }
+ @GuardedBy("mPriorityQueue")
+ private boolean stackHasMessages(Handler h, int what, Object object, Runnable r, long when,
+ MessageCompare compare, boolean removeMatches) {
+ boolean found = false;
+ StackNode top = (StackNode) sState.getVolatile(this);
+ StateNode bottom = getStateNode(top);
+
+ /* No messages to search. */
+ if (!top.isMessageNode()) {
+ return false;
+ }
+
+ /*
+ * We have messages that we may tombstone. Walk the stack until we hit the bottom.
+ * next() will remove them on it's next pass.
+ */
+ if (!(top instanceof MessageNode)) {
+ Log.wtf(TAG, "Unknown node type found in Trieber stack");
+ }
+ MessageNode p = (MessageNode) top;
+
+ while (true) {
+ if (compare.compareMessage(p.mMessage, h, what, object, r, when)) {
+ found = true;
+ if (DEBUG) {
+ Log.w(TAG, "stackHasMessages node matches");
+ }
+ if (removeMatches) {
+ if (p.removeFromStack()) {
+ p.mMessage.recycleUnchecked();
+ if (mMessageCounts.incrementCancelled()) {
+ nativeWake(mPtr);
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+
+ StackNode n = p.mNext;
+ if (!n.isMessageNode()) {
+ /* We reached the end of the stack */
+ return found;
+ }
+ p = (MessageNode) n;
+ }
+ }
+
+ @GuardedBy("mPriorityQueue")
+ private boolean priorityQueueHasMessage(PriorityQueue queue, Handler h,
+ int what, Object object, Runnable r, long when, MessageCompare compare,
+ boolean removeMatches) {
+ Iterator<MessageNode> iterator = queue.iterator();
+ boolean found = false;
+
+ while (iterator.hasNext()) {
+ MessageNode msg = iterator.next();
+
+ if (compare.compareMessage(msg.mMessage, h, what, object, r, when)) {
+ if (removeMatches) {
+ found = true;
+ iterator.remove();
+ msg.mMessage.recycleUnchecked();
+ } else {
+ return true;
+ }
+ }
+ }
+ return found;
+ }
+
+ private boolean findOrRemoveMessages(Handler h, int what, Object object, Runnable r, long when,
+ MessageCompare compare, boolean removeMatches) {
+ boolean foundInStack, foundInQueue;
+
+ synchronized (mPriorityQueue) {
+ foundInStack = stackHasMessages(h, what, object, r, when, compare, removeMatches);
+ foundInQueue = priorityQueueHasMessage(mPriorityQueue, h, what, object, r, when,
+ compare, removeMatches);
+ foundInQueue |= priorityQueueHasMessage(mAsyncPriorityQueue, h, what, object, r, when,
+ compare, removeMatches);
+
+ return foundInStack || foundInQueue;
+ }
+ }
+
+ private static class MatchHandlerWhatAndObject extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.what == what && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerWhatAndObject mMatchHandlerWhatAndObject =
+ new MatchHandlerWhatAndObject();
+ boolean hasMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, false);
+ }
+
+ private static class MatchHandlerWhatAndObjectEquals extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.what == what && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerWhatAndObjectEquals mMatchHandlerWhatAndObjectEquals =
+ new MatchHandlerWhatAndObjectEquals();
+ boolean hasEqualMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals,
+ false);
+ }
+
+ private static class MatchHandlerRunnableAndObject extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.callback == r && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerRunnableAndObject mMatchHandlerRunnableAndObject =
+ new MatchHandlerRunnableAndObject();
+
+ boolean hasMessages(Handler h, Runnable r, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, false);
+ }
+
+ private static class MatchHandler extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandler mMatchHandler = new MatchHandler();
+ boolean hasMessages(Handler h) {
+ if (h == null) {
+ return false;
+ }
+ return findOrRemoveMessages(h, -1, null, null, 0, mMatchHandler, false);
+ }
+
+ void removeMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, true);
+ }
+
+ void removeEqualMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, true);
+ }
+
+ void removeMessages(Handler h, Runnable r, Object object) {
+ if (h == null || r == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true);
+ }
+
+ private static class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.callback == r && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerRunnableAndObjectEquals mMatchHandlerRunnableAndObjectEquals =
+ new MatchHandlerRunnableAndObjectEquals();
+ void removeEqualMessages(Handler h, Runnable r, Object object) {
+ if (h == null || r == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true);
+ }
+
+ private static class MatchHandlerAndObject extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerAndObject mMatchHandlerAndObject = new MatchHandlerAndObject();
+ void removeCallbacksAndMessages(Handler h, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true);
+ }
+
+ private static class MatchHandlerAndObjectEquals extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchHandlerAndObjectEquals mMatchHandlerAndObjectEquals =
+ new MatchHandlerAndObjectEquals();
+ void removeCallbacksAndEqualMessages(Handler h, Object object) {
+ if (h == null) {
+ return;
+ }
+ findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true);
+ }
+
+ private static class MatchAllMessages extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ return true;
+ }
+ }
+ private final MatchAllMessages mMatchAllMessages = new MatchAllMessages();
+ private void removeAllMessages() {
+ findOrRemoveMessages(null, -1, null, null, 0, mMatchAllMessages, true);
+ }
+
+ private static class MatchAllFutureMessages extends MessageCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.when > when) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private final MatchAllFutureMessages mMatchAllFutureMessages = new MatchAllFutureMessages();
+ private void removeAllFutureMessages() {
+ findOrRemoveMessages(null, -1, null, null, SystemClock.uptimeMillis(),
+ mMatchAllFutureMessages, true);
+ }
+
+ private void printPriorityQueueNodes() {
+ Iterator<MessageNode> iterator = mPriorityQueue.iterator();
+
+ Log.d(TAG, "* Dump priority queue");
+ while (iterator.hasNext()) {
+ MessageNode msgNode = iterator.next();
+ Log.d(TAG, "** MessageNode what: " + msgNode.mMessage.what + " when "
+ + msgNode.mMessage.when + " seq: " + msgNode.mInsertSeq);
+ }
+ }
+
+ private int dumpPriorityQueue(PriorityQueue<MessageNode> queue, Printer pw, String prefix,
+ Handler h, int n) {
+ int count = 0;
+ long now = SystemClock.uptimeMillis();
+
+ for (MessageNode msgNode : queue) {
+ Message msg = msgNode.mMessage;
+ if (h == null || h == msg.target) {
+ pw.println(prefix + "Message " + (n + count) + ": " + msg.toString(now));
+ }
+ count++;
+ }
+ return count;
+ }
+
+ void dump(Printer pw, String prefix, Handler h) {
+ long now = SystemClock.uptimeMillis();
+ int n = 0;
+
+ pw.println(prefix + "(MessageQueue is using SemiConcurrent implementation)");
+
+ StackNode node = (StackNode) sState.getVolatile(this);
+ while (node != null) {
+ if (node.isMessageNode()) {
+ Message msg = ((MessageNode) node).mMessage;
+ if (h == null || h == msg.target) {
+ pw.println(prefix + "Message " + n + ": " + msg.toString(now));
+ }
+ node = ((MessageNode) node).mNext;
+ } else {
+ pw.println(prefix + "State: " + node);
+ node = null;
+ }
+ n++;
+ }
+
+ synchronized (mPriorityQueue) {
+ pw.println(prefix + "PriorityQueue Messages: ");
+ n += dumpPriorityQueue(mPriorityQueue, pw, prefix, h, n);
+ pw.println(prefix + "AsyncPriorityQueue Messages: ");
+ n += dumpPriorityQueue(mAsyncPriorityQueue, pw, prefix, h, n);
+ }
+
+ pw.println(prefix + "(Total messages: " + n + ", polling=" + isPolling()
+ + ", quitting=" + (boolean) sQuitting.getVolatile(this) + ")");
+ }
+
+ private int dumpPriorityQueue(PriorityQueue<MessageNode> queue, ProtoOutputStream proto) {
+ int count = 0;
+
+ for (MessageNode msgNode : queue) {
+ Message msg = msgNode.mMessage;
+ msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+ count++;
+ }
+ return count;
+ }
+
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ final long messageQueueToken = proto.start(fieldId);
+
+ StackNode node = (StackNode) sState.getVolatile(this);
+ while (node.isMessageNode()) {
+ Message msg = ((MessageNode) node).mMessage;
+ msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+ node = ((MessageNode) node).mNext;
+ }
+
+ synchronized (mPriorityQueue) {
+ dumpPriorityQueue(mPriorityQueue, proto);
+ dumpPriorityQueue(mAsyncPriorityQueue, proto);
+ }
+
+ proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPolling());
+ proto.write(MessageQueueProto.IS_QUITTING, (boolean) sQuitting.getVolatile(this));
+ proto.end(messageQueueToken);
+ }
+
+ /**
+ * Adds a file descriptor listener to receive notification when file descriptor
+ * related events occur.
+ * <p>
+ * If the file descriptor has already been registered, the specified events
+ * and listener will replace any that were previously associated with it.
+ * It is not possible to set more than one listener per file descriptor.
+ * </p><p>
+ * It is important to always unregister the listener when the file descriptor
+ * is no longer of use.
+ * </p>
+ *
+ * @param fd The file descriptor for which a listener will be registered.
+ * @param events The set of events to receive: a combination of the
+ * {@link OnFileDescriptorEventListener#EVENT_INPUT},
+ * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and
+ * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks. If the requested
+ * set of events is zero, then the listener is unregistered.
+ * @param listener The listener to invoke when file descriptor events occur.
+ *
+ * @see OnFileDescriptorEventListener
+ * @see #removeOnFileDescriptorEventListener
+ */
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
+ @OnFileDescriptorEventListener.Events int events,
+ @NonNull OnFileDescriptorEventListener listener) {
+ if (fd == null) {
+ throw new IllegalArgumentException("fd must not be null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ synchronized (mFileDescriptorRecordsLock) {
+ updateOnFileDescriptorEventListenerLocked(fd, events, listener);
+ }
+ }
+
+ /**
+ * Removes a file descriptor listener.
+ * <p>
+ * This method does nothing if no listener has been registered for the
+ * specified file descriptor.
+ * </p>
+ *
+ * @param fd The file descriptor whose listener will be unregistered.
+ *
+ * @see OnFileDescriptorEventListener
+ * @see #addOnFileDescriptorEventListener
+ */
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
+ if (fd == null) {
+ throw new IllegalArgumentException("fd must not be null");
+ }
+
+ synchronized (mFileDescriptorRecordsLock) {
+ updateOnFileDescriptorEventListenerLocked(fd, 0, null);
+ }
+ }
+
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
+ OnFileDescriptorEventListener listener) {
+ final int fdNum = fd.getInt$();
+
+ int index = -1;
+ FileDescriptorRecord record = null;
+ if (mFileDescriptorRecords != null) {
+ index = mFileDescriptorRecords.indexOfKey(fdNum);
+ if (index >= 0) {
+ record = mFileDescriptorRecords.valueAt(index);
+ if (record != null && record.mEvents == events) {
+ return;
+ }
+ }
+ }
+
+ if (events != 0) {
+ events |= OnFileDescriptorEventListener.EVENT_ERROR;
+ if (record == null) {
+ if (mFileDescriptorRecords == null) {
+ mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();
+ }
+ record = new FileDescriptorRecord(fd, events, listener);
+ mFileDescriptorRecords.put(fdNum, record);
+ } else {
+ record.mListener = listener;
+ record.mEvents = events;
+ record.mSeq += 1;
+ }
+ nativeSetFileDescriptorEvents(mPtr, fdNum, events);
+ } else if (record != null) {
+ record.mEvents = 0;
+ mFileDescriptorRecords.removeAt(index);
+ nativeSetFileDescriptorEvents(mPtr, fdNum, 0);
+ }
+ }
+
+ // Called from native code.
+ private int dispatchEvents(int fd, int events) {
+ // Get the file descriptor record and any state that might change.
+ final FileDescriptorRecord record;
+ final int oldWatchedEvents;
+ final OnFileDescriptorEventListener listener;
+ final int seq;
+ synchronized (mFileDescriptorRecordsLock) {
+ record = mFileDescriptorRecords.get(fd);
+ if (record == null) {
+ return 0; // spurious, no listener registered
+ }
+
+ oldWatchedEvents = record.mEvents;
+ events &= oldWatchedEvents; // filter events based on current watched set
+ if (events == 0) {
+ return oldWatchedEvents; // spurious, watched events changed
+ }
+
+ listener = record.mListener;
+ seq = record.mSeq;
+ }
+
+ // Invoke the listener outside of the lock.
+ int newWatchedEvents = listener.onFileDescriptorEvents(
+ record.mDescriptor, events);
+ if (newWatchedEvents != 0) {
+ newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;
+ }
+
+ // Update the file descriptor record if the listener changed the set of
+ // events to watch and the listener itself hasn't been updated since.
+ if (newWatchedEvents != oldWatchedEvents) {
+ synchronized (mFileDescriptorRecordsLock) {
+ int index = mFileDescriptorRecords.indexOfKey(fd);
+ if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+ && record.mSeq == seq) {
+ record.mEvents = newWatchedEvents;
+ if (newWatchedEvents == 0) {
+ mFileDescriptorRecords.removeAt(index);
+ }
+ }
+ }
+ }
+
+ // Return the new set of events to watch for native code to take care of.
+ return newWatchedEvents;
+ }
+
+ /**
+ * Callback interface for discovering when a thread is going to block
+ * waiting for more messages.
+ */
+ public static interface IdleHandler {
+ /**
+ * Called when the message queue has run out of messages and will now
+ * wait for more. Return true to keep your idle handler active, false
+ * to have it removed. This may be called if there are still messages
+ * pending in the queue, but they are all scheduled to be dispatched
+ * after the current time.
+ */
+ boolean queueIdle();
+ }
+
+ /**
+ * A listener which is invoked when file descriptor related events occur.
+ */
+ public interface OnFileDescriptorEventListener {
+ /**
+ * File descriptor event: Indicates that the file descriptor is ready for input
+ * operations, such as reading.
+ * <p>
+ * The listener should read all available data from the file descriptor
+ * then return <code>true</code> to keep the listener active or <code>false</code>
+ * to remove the listener.
+ * </p><p>
+ * In the case of a socket, this event may be generated to indicate
+ * that there is at least one incoming connection that the listener
+ * should accept.
+ * </p><p>
+ * This event will only be generated if the {@link #EVENT_INPUT} event mask was
+ * specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_INPUT = 1 << 0;
+
+ /**
+ * File descriptor event: Indicates that the file descriptor is ready for output
+ * operations, such as writing.
+ * <p>
+ * The listener should write as much data as it needs. If it could not
+ * write everything at once, then it should return <code>true</code> to
+ * keep the listener active. Otherwise, it should return <code>false</code>
+ * to remove the listener then re-register it later when it needs to write
+ * something else.
+ * </p><p>
+ * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was
+ * specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_OUTPUT = 1 << 1;
+
+ /**
+ * File descriptor event: Indicates that the file descriptor encountered a
+ * fatal error.
+ * <p>
+ * File descriptor errors can occur for various reasons. One common error
+ * is when the remote peer of a socket or pipe closes its end of the connection.
+ * </p><p>
+ * This event may be generated at any time regardless of whether the
+ * {@link #EVENT_ERROR} event mask was specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_ERROR = 1 << 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = { "EVENT_" }, value = {
+ EVENT_INPUT,
+ EVENT_OUTPUT,
+ EVENT_ERROR
+ })
+ public @interface Events {}
+
+ /**
+ * Called when a file descriptor receives events.
+ *
+ * @param fd The file descriptor.
+ * @param events The set of events that occurred: a combination of the
+ * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks.
+ * @return The new set of events to watch, or 0 to unregister the listener.
+ *
+ * @see #EVENT_INPUT
+ * @see #EVENT_OUTPUT
+ * @see #EVENT_ERROR
+ */
+ @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events);
+ }
+
+ static final class FileDescriptorRecord {
+ public final FileDescriptor mDescriptor;
+ public int mEvents;
+ public OnFileDescriptorEventListener mListener;
+ public int mSeq;
+
+ public FileDescriptorRecord(FileDescriptor descriptor,
+ int events, OnFileDescriptorEventListener listener) {
+ mDescriptor = descriptor;
+ mEvents = events;
+ mListener = listener;
+ }
+ }
+}
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index f2143f6..7b91dd5 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -50,7 +50,7 @@
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
- mServiceManager = IServiceManager.Stub.asInterface(remote);
+ mServiceManager = IServiceManager.Stub.asInterface(this.getNativeServiceManager());
}
public IBinder asBinder() {
@@ -128,4 +128,6 @@
private IBinder mRemote;
private IServiceManager mServiceManager;
+
+ private native IBinder getNativeServiceManager();
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7926afe..f30a9f5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -6367,6 +6367,33 @@
Settings.Global.DEVICE_DEMO_MODE, 0) > 0;
}
+ private static final String CACHE_KEY_USER_SERIAL_NUMBER_PROPERTY =
+ PropertyInvalidatedCache.createPropertyName(
+ PropertyInvalidatedCache.MODULE_SYSTEM, "user_serial_number");
+
+ private final PropertyInvalidatedCache<Integer, Integer> mUserSerialNumberCache =
+ new PropertyInvalidatedCache<Integer, Integer>(
+ 32, CACHE_KEY_USER_SERIAL_NUMBER_PROPERTY) {
+ @Override
+ public Integer recompute(Integer query) {
+ try {
+ return mService.getUserSerialNumber(query);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+ @Override
+ public boolean bypass(Integer query) {
+ return query <= 0;
+ }
+ };
+
+
+ /** @hide */
+ public static final void invalidateUserSerialNumberCache() {
+ PropertyInvalidatedCache.invalidateCache(CACHE_KEY_USER_SERIAL_NUMBER_PROPERTY);
+ }
+
/**
* Returns a serial number on this device for a given userId. User handles can be recycled
* when deleting and creating users, but serial numbers are not reused until the device is wiped.
@@ -6376,6 +6403,14 @@
*/
@UnsupportedAppUsage
public int getUserSerialNumber(@UserIdInt int userId) {
+ if (android.multiuser.Flags.cacheUserSerialNumber()) {
+ // System user serial number is always 0, and it always exists.
+ // There is no need to call binder for that.
+ if (userId == UserHandle.USER_SYSTEM) {
+ return UserHandle.USER_SERIAL_SYSTEM;
+ }
+ return mUserSerialNumberCache.query(userId);
+ }
try {
return mService.getUserSerialNumber(userId);
} catch (RemoteException re) {
diff --git a/core/java/android/os/connectivity/CellularBatteryStats.java b/core/java/android/os/connectivity/CellularBatteryStats.java
index fc17002..1649ed5 100644
--- a/core/java/android/os/connectivity/CellularBatteryStats.java
+++ b/core/java/android/os/connectivity/CellularBatteryStats.java
@@ -15,11 +15,13 @@
*/
package android.os.connectivity;
+import android.annotation.FlaggedApi;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.BatteryStats;
import android.os.Parcel;
import android.os.Parcelable;
@@ -35,6 +37,7 @@
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
@SystemApi
public final class CellularBatteryStats implements Parcelable {
@@ -83,11 +86,17 @@
}
};
- /** @hide **/
+ /**
+ * This constructor should only be used in tests.
+ * @hide
+ */
+ @FlaggedApi(
+ com.android.server.power.optimization.Flags.FLAG_STREAMLINED_CONNECTIVITY_BATTERY_STATS)
+ @TestApi
public CellularBatteryStats(long loggingDurationMs, long kernelActiveTimeMs, long numPacketsTx,
long numBytesTx, long numPacketsRx, long numBytesRx, long sleepTimeMs, long idleTimeMs,
- long rxTimeMs, Long energyConsumedMaMs, long[] timeInRatMs,
- long[] timeInRxSignalStrengthLevelMs, long[] txTimeMs,
+ long rxTimeMs, long energyConsumedMaMs, @NonNull long[] timeInRatMs,
+ @NonNull long[] timeInRxSignalStrengthLevelMs, @NonNull long[] txTimeMs,
long monitoredRailChargeConsumedMaMs) {
mLoggingDurationMs = loggingDurationMs;
@@ -270,7 +279,6 @@
* @return The amount of time the phone spends in the {@code networkType} network type. The
* unit is in microseconds.
*/
- @NonNull
@SuppressLint("MethodNameUnits")
public long getTimeInRatMicros(@NetworkType int networkType) {
if (networkType >= mTimeInRatMs.length) {
@@ -289,7 +297,6 @@
* @return Amount of time phone spends in specific cellular rx signal strength levels
* in microseconds. The index is signal strength bin.
*/
- @NonNull
@SuppressLint("MethodNameUnits")
public long getTimeInRxSignalStrengthLevelMicros(
@IntRange(from = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
@@ -315,10 +322,9 @@
* <li> index 3 = 15dBm < tx_power < 20dBm. </li>
* <li> index 4 = tx_power > 20dBm. </li>
* </ul>
- *
- * @hide
*/
- @NonNull
+ @FlaggedApi(
+ com.android.server.power.optimization.Flags.FLAG_STREAMLINED_CONNECTIVITY_BATTERY_STATS)
public long getTxTimeMillis(
@IntRange(from = ModemActivityInfo.TX_POWER_LEVEL_0,
to = ModemActivityInfo.TX_POWER_LEVEL_4) int level) {
diff --git a/core/java/android/os/connectivity/WifiBatteryStats.java b/core/java/android/os/connectivity/WifiBatteryStats.java
index 7e6ebcf..79e0be8 100644
--- a/core/java/android/os/connectivity/WifiBatteryStats.java
+++ b/core/java/android/os/connectivity/WifiBatteryStats.java
@@ -19,9 +19,11 @@
import static android.os.BatteryStatsManager.NUM_WIFI_STATES;
import static android.os.BatteryStatsManager.NUM_WIFI_SUPPL_STATES;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -34,6 +36,7 @@
* @hide
*/
@SystemApi
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class WifiBatteryStats implements Parcelable {
private final long mLoggingDurationMillis;
private final long mKernelActiveTimeMillis;
@@ -150,7 +153,13 @@
mMonitoredRailChargeConsumedMaMillis);
}
- /** @hide **/
+ /**
+ * This constructor should only be used in tests.
+ * @hide
+ */
+ @FlaggedApi(
+ com.android.server.power.optimization.Flags.FLAG_STREAMLINED_CONNECTIVITY_BATTERY_STATS)
+ @TestApi
public WifiBatteryStats(long loggingDurationMillis, long kernelActiveTimeMillis,
long numPacketsTx, long numBytesTx, long numPacketsRx, long numBytesRx,
long sleepTimeMillis, long scanTimeMillis, long idleTimeMillis, long rxTimeMillis,
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 76cf901..6458534 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -76,6 +76,14 @@
}
flag {
+ name: "ordered_broadcast_multiple_permissions"
+ is_exported: true
+ namespace: "bluetooth"
+ description: "Guards the Context.sendOrderedBroadcastMultiplePermissions API"
+ bug: "345802719"
+}
+
+flag {
name: "battery_saver_supported_check_api"
is_exported: true
namespace: "backstage_power"
diff --git a/core/java/android/os/vibrator/persistence/ParsedVibration.java b/core/java/android/os/vibrator/persistence/ParsedVibration.java
index e5543ab..74d3a7b 100644
--- a/core/java/android/os/vibrator/persistence/ParsedVibration.java
+++ b/core/java/android/os/vibrator/persistence/ParsedVibration.java
@@ -27,6 +27,7 @@
import android.os.Vibrator;
import android.os.VibratorInfo;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -41,17 +42,18 @@
@SystemApi
@FlaggedApi(FLAG_VIBRATION_XML_APIS)
public final class ParsedVibration {
- private final List<VibrationEffect> mEffects;
+ private final ArrayList<VibrationEffect> mEffects;
/** @hide */
@TestApi
public ParsedVibration(@NonNull List<VibrationEffect> effects) {
- mEffects = effects;
+ mEffects = new ArrayList<>(effects);
}
/** @hide */
public ParsedVibration(@NonNull VibrationEffect effect) {
- mEffects = List.of(effect);
+ mEffects = new ArrayList<>(1);
+ mEffects.add(effect);
}
/**
@@ -100,4 +102,11 @@
public int hashCode() {
return Objects.hashCode(mEffects);
}
+
+ @Override
+ public String toString() {
+ return "ParsedVibration{"
+ + "effects=" + mEffects
+ + '}';
+ }
}
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index e029e52..5ef597d 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -213,3 +213,11 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "location_bypass_privacy_dashboard_enabled"
+ is_exported: true
+ namespace: "permissions"
+ description: "Show access entry of location bypass permission in the Privacy Dashboard"
+ bug: "325536053"
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4e8a04f..94c76929 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1403,6 +1403,19 @@
"android.settings.QUICK_LAUNCH_SETTINGS";
/**
+ * Activity Action: Showing settings to manage adaptive notifications.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_ADAPTIVE_NOTIFICATIONS =
+ "android.settings.MANAGE_ADAPTIVE_NOTIFICATIONS";
+
+ /**
* Activity Action: Show settings to manage installed applications.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
@@ -11072,6 +11085,13 @@
"active_unlock_on_biometric_fail";
/**
+ * Whether or not active unlock triggers on legacy unlock intents.
+ * @hide
+ */
+ public static final String ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY =
+ "active_unlock_on_unlock_intent_legacy";
+
+ /**
* If active unlock triggers on biometric failures, include the following error codes
* as a biometric failure. See {@link android.hardware.biometrics.BiometricFaceConstants}.
* Error codes should be separated by a pipe. For example: "1|4|5". If active unlock
@@ -13376,7 +13396,19 @@
= "enable_freeform_support";
/**
- * Whether to enable experimental desktop mode on secondary displays.
+ * Whether to override the availability of the desktop mode on the main display of the
+ * device. If on, users can make move an app to the desktop, allowing a freeform windowing
+ * experience.
+ * @hide
+ */
+ @Readable
+ public static final String DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES =
+ "override_desktop_mode_features";
+
+ /**
+ * Whether to enable the legacy freeform support on secondary displays. If enabled, the
+ * SECONDARY_HOME of the launcher is started on any secondary display, allowing for a
+ * desktop experience.
* @hide
*/
@Readable
@@ -20087,7 +20119,7 @@
* (0 = false, 1 = true)
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String REDUCE_MOTION = "reduce_motion";
/**
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 88bd87e..d019bad 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4940,7 +4940,7 @@
*
* @hide
*/
- public static final String COLUMN_IS_NTN = "is_ntn";
+ public static final String COLUMN_IS_ONLY_NTN = "is_only_ntn";
/**
* TelephonyProvider column name for transferred status
@@ -4976,6 +4976,15 @@
public static final String COLUMN_SATELLITE_ENTITLEMENT_PLMNS =
"satellite_entitlement_plmns";
+ /**
+ * TelephonyProvider column name to indicate the satellite ESOS supported. The value of this
+ * column is set based on {@link CarrierConfigManager#KEY_SATELLITE_ESOS_SUPPORTED_BOOL}.
+ * By default, it's disabled.
+ *
+ * @hide
+ */
+ public static final String COLUMN_SATELLITE_ESOS_SUPPORTED = "satellite_esos_supported";
+
/** All columns in {@link SimInfo} table. */
private static final List<String> ALL_COLUMNS = List.of(
COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
@@ -5047,11 +5056,12 @@
COLUMN_USER_HANDLE,
COLUMN_SATELLITE_ENABLED,
COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER,
- COLUMN_IS_NTN,
+ COLUMN_IS_ONLY_NTN,
COLUMN_SERVICE_CAPABILITIES,
COLUMN_TRANSFER_STATUS,
COLUMN_SATELLITE_ENTITLEMENT_STATUS,
- COLUMN_SATELLITE_ENTITLEMENT_PLMNS
+ COLUMN_SATELLITE_ENTITLEMENT_PLMNS,
+ COLUMN_SATELLITE_ESOS_SUPPORTED
);
/**
diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig
index ed20207..82c1613 100644
--- a/core/java/android/service/chooser/flags.aconfig
+++ b/core/java/android/service/chooser/flags.aconfig
@@ -2,14 +2,6 @@
container: "system"
flag {
- name: "chooser_album_text"
- is_exported: true
- namespace: "intentresolver"
- description: "Flag controlling the album text subtype hint for sharesheet"
- bug: "323380224"
-}
-
-flag {
name: "enable_sharesheet_metadata_extra"
is_exported: true
namespace: "intentresolver"
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 8ecb1fb..6b0d301 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -19,6 +19,7 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.service.dreams.Flags.dreamHandlesConfirmKeys;
import static android.service.dreams.Flags.dreamHandlesBeingObscured;
+import static android.service.dreams.Flags.startAndStopDozingInBackground;
import android.annotation.FlaggedApi;
import android.annotation.IdRes;
@@ -923,9 +924,16 @@
if (mDozing) {
try {
- mDreamManager.startDozing(
+ if (startAndStopDozingInBackground()) {
+ mDreamManager.startDozingOneway(
mDreamToken, mDozeScreenState, mDozeScreenStateReason,
mDozeScreenBrightness);
+ } else {
+ mDreamManager.startDozing(
+ mDreamToken, mDozeScreenState, mDozeScreenStateReason,
+ mDozeScreenBrightness);
+ }
+
} catch (RemoteException ex) {
// system server died
}
@@ -1250,7 +1258,11 @@
try {
// finishSelf will unbind the dream controller from the dream service. This will
// trigger DreamService.this.onDestroy and DreamService.this will die.
- mDreamManager.finishSelf(mDreamToken, true /*immediate*/);
+ if (startAndStopDozingInBackground()) {
+ mDreamManager.finishSelfOneway(mDreamToken, true /*immediate*/);
+ } else {
+ mDreamManager.finishSelf(mDreamToken, true /*immediate*/);
+ }
} catch (RemoteException ex) {
// system server died
}
@@ -1393,7 +1405,8 @@
convertToComponentName(
rawMetadata.getString(
com.android.internal.R.styleable.Dream_settingsActivity),
- serviceInfo),
+ serviceInfo,
+ packageManager),
rawMetadata.getDrawable(
com.android.internal.R.styleable.Dream_previewImage),
rawMetadata.getBoolean(R.styleable.Dream_showClockAndComplications,
@@ -1408,26 +1421,38 @@
}
@Nullable
- private static ComponentName convertToComponentName(@Nullable String flattenedString,
- ServiceInfo serviceInfo) {
+ private static ComponentName convertToComponentName(
+ @Nullable String flattenedString,
+ ServiceInfo serviceInfo,
+ PackageManager packageManager) {
if (flattenedString == null) {
return null;
}
- if (!flattenedString.contains("/")) {
- return new ComponentName(serviceInfo.packageName, flattenedString);
+ final ComponentName cn =
+ flattenedString.contains("/")
+ ? ComponentName.unflattenFromString(flattenedString)
+ : new ComponentName(serviceInfo.packageName, flattenedString);
+
+ if (cn == null) {
+ return null;
}
// Ensure that the component is from the same package as the dream service. If not,
// treat the component as invalid and return null instead.
- final ComponentName cn = ComponentName.unflattenFromString(flattenedString);
- if (cn == null) return null;
if (!cn.getPackageName().equals(serviceInfo.packageName)) {
Log.w(TAG,
"Inconsistent package name in component: " + cn.getPackageName()
+ ", should be: " + serviceInfo.packageName);
return null;
}
+
+ // Ensure that the activity exists. If not, treat the component as invalid and return null.
+ if (new Intent().setComponent(cn).resolveActivityInfo(packageManager, 0) == null) {
+ Log.w(TAG, "Dream settings activity not found: " + cn);
+ return null;
+ }
+
return cn;
}
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index cf98bfe0..620eef6 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -50,4 +50,6 @@
void startDreamActivity(in Intent intent);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)")
oneway void setDreamIsObscured(in boolean isObscured);
+ oneway void startDozingOneway(in IBinder token, int screenState, int reason, int screenBrightness);
+ oneway void finishSelfOneway(in IBinder token, boolean immediate);
}
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index 54d950c..83e0adf 100644
--- a/core/java/android/service/dreams/flags.aconfig
+++ b/core/java/android/service/dreams/flags.aconfig
@@ -47,3 +47,13 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "start_and_stop_dozing_in_background"
+ namespace: "systemui"
+ description: "Move the start-dozing and stop-dozing operation to the background"
+ bug: "330287187"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 63410c7..073f512 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -184,7 +184,6 @@
/** @hide */
@IntDef(prefix = { "TYPE_" }, value = {
- TYPE_UNKNOWN,
TYPE_OTHER,
TYPE_PROMOTION,
TYPE_SOCIAL_MEDIA,
@@ -195,12 +194,8 @@
public @interface Types {}
/**
- * The type of this notification is unknown.
- */
- @FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
- public static final int TYPE_UNKNOWN = -1;
- /**
- * The type of this notification is not one of ones known to the NotificationAssistantService.
+ * This notification can be categorized, but not into one of the other categories known to the
+ * OS at a given version.
*/
@FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public static final int TYPE_OTHER = 0;
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 3161ff1..46b222b 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,7 +16,6 @@
package android.service.wallpaper;
-import static android.app.WallpaperManager.COMMAND_DISPLAY_SWITCH;
import static android.app.WallpaperManager.COMMAND_FREEZE;
import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WallpaperManager.SetWallpaperFlags;
@@ -161,7 +160,6 @@
static final boolean DEBUG = false;
static final float MIN_PAGE_ALLOWED_MARGIN = .05f;
private static final int MIN_BITMAP_SCREENSHOT_WIDTH = 64;
- private static final long PRESERVE_VISIBLE_TIMEOUT_MS = 1000;
private static final long DEFAULT_UPDATE_SCREENSHOT_DURATION = 60 * 1000; //Once per minute
private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
new RectF(0, 0, 1, 1);
@@ -174,7 +172,6 @@
private static final int MSG_UPDATE_SURFACE = 10000;
private static final int MSG_VISIBILITY_CHANGED = 10010;
- private static final int MSG_REFRESH_VISIBILITY = 10011;
private static final int MSG_WALLPAPER_OFFSETS = 10020;
private static final int MSG_WALLPAPER_COMMAND = 10025;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -258,11 +255,6 @@
*/
private boolean mIsScreenTurningOn;
boolean mReportedVisible;
- /**
- * This is used with {@link #PRESERVE_VISIBLE_TIMEOUT_MS} to avoid intermediate visibility
- * changes if the display may be toggled in a short time, e.g. display switch.
- */
- boolean mPreserveVisible;
boolean mDestroyed;
// Set to true after receiving WallpaperManager#COMMAND_FREEZE. It's reset back to false
// after receiving WallpaperManager#COMMAND_UNFREEZE. COMMAND_FREEZE is fully applied once
@@ -1107,9 +1099,6 @@
if (pendingCount != 0) {
out.print(prefix); out.print("mPendingResizeCount="); out.println(pendingCount);
}
- if (mPreserveVisible) {
- out.print(prefix); out.print("mPreserveVisible=true");
- }
synchronized (mLock) {
out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
out.print(" mPendingXOffset="); out.println(mPendingXOffset);
@@ -1672,8 +1661,7 @@
? false
: mIWallpaperEngine.mInfo.supportsAmbientMode();
// Report visibility only if display is fully on or wallpaper supports ambient mode.
- final boolean visible = (mVisible && (displayFullyOn || supportsAmbientMode))
- || mPreserveVisible;
+ final boolean visible = mVisible && (displayFullyOn || supportsAmbientMode);
if (DEBUG) {
Log.v(
TAG,
@@ -2110,9 +2098,6 @@
if (!mDestroyed) {
if (COMMAND_FREEZE.equals(cmd.action) || COMMAND_UNFREEZE.equals(cmd.action)) {
updateFrozenState(/* frozenRequested= */ !COMMAND_UNFREEZE.equals(cmd.action));
- } else if (COMMAND_DISPLAY_SWITCH.equals(cmd.action)) {
- handleDisplaySwitch(cmd.z == 1 /* startToSwitch */);
- return;
}
result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
cmd.extras, cmd.sync);
@@ -2128,23 +2113,6 @@
}
}
- private void handleDisplaySwitch(boolean startToSwitch) {
- if (startToSwitch && mReportedVisible) {
- // The display may be off/on in a short time when the display is switching.
- // Keep the visible state until onScreenTurnedOn or !startToSwitch is received, so
- // the rendering thread can be active to redraw in time when receiving size change.
- mPreserveVisible = true;
- mCaller.removeMessages(MSG_REFRESH_VISIBILITY);
- mCaller.sendMessageDelayed(mCaller.obtainMessage(MSG_REFRESH_VISIBILITY),
- PRESERVE_VISIBLE_TIMEOUT_MS);
- } else if (!startToSwitch && mPreserveVisible) {
- // The switch is finished, so restore to actual visibility.
- mPreserveVisible = false;
- mCaller.removeMessages(MSG_REFRESH_VISIBILITY);
- reportVisibility(false /* forceReport */);
- }
- }
-
private void updateFrozenState(boolean frozenRequested) {
if (mIWallpaperEngine.mInfo == null
// Procees the unfreeze command in case the wallaper became static while
@@ -2691,10 +2659,6 @@
+ ": " + message.arg1);
mEngine.doVisibilityChanged(message.arg1 != 0);
break;
- case MSG_REFRESH_VISIBILITY:
- mEngine.mPreserveVisible = false;
- mEngine.reportVisibility(false /* forceReport */);
- break;
case MSG_UPDATE_SCREEN_TURNING_ON:
if (DEBUG) {
Log.v(TAG,
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index d7389ba..be60c25 100644
--- a/core/java/android/tracing/flags.aconfig
+++ b/core/java/android/tracing/flags.aconfig
@@ -38,3 +38,11 @@
is_fixed_read_only: true
bug: "323166383"
}
+
+flag {
+ name: "perfetto_wm_tracing"
+ namespace: "windowing_tools"
+ description: "Migrate WindowManager tracing to Perfetto"
+ is_fixed_read_only: true
+ bug: "323165543"
+}
diff --git a/core/java/android/view/IPinnedTaskListener.aidl b/core/java/android/view/IPinnedTaskListener.aidl
index e4e2d6f..3bd1506 100644
--- a/core/java/android/view/IPinnedTaskListener.aidl
+++ b/core/java/android/view/IPinnedTaskListener.aidl
@@ -42,12 +42,4 @@
* with fromImeAdjustement set to {@code true}.
*/
void onImeVisibilityChanged(boolean imeVisible, int imeHeight);
-
- /**
- * Called by the window manager to notify the listener that Activity (was or is in pinned mode)
- * is hidden (either stopped or removed). This is generally used as a signal to reset saved
- * reentry fraction and size.
- * {@param componentName} represents the application component of PiP window.
- */
- void onActivityHidden(in ComponentName componentName);
}
diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java
index fc1852d..c7e93c1 100644
--- a/core/java/android/view/ImeBackAnimationController.java
+++ b/core/java/android/view/ImeBackAnimationController.java
@@ -27,6 +27,7 @@
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.WindowConfiguration;
import android.graphics.Insets;
import android.util.Log;
import android.view.animation.BackGestureInterpolator;
@@ -137,9 +138,10 @@
@Override
public void onBackInvoked() {
if (!isBackAnimationAllowed() || !mIsPreCommitAnimationInProgress) {
- // play regular hide animation if back-animation is not allowed or if insets control has
- // been cancelled by the system (this can happen in split screen for example)
- mInsetsController.hide(ime());
+ // play regular hide animation if predictive back-animation is not allowed or if insets
+ // control has been cancelled by the system. This can happen in multi-window mode for
+ // example (i.e. split-screen or activity-embedding)
+ notifyHideIme();
return;
}
startPostCommitAnim(/*hideIme*/ true);
@@ -209,6 +211,11 @@
if (triggerBack) {
mInsetsController.setPredictiveBackImeHideAnimInProgress(true);
notifyHideIme();
+ // requesting IME as invisible during post-commit
+ mInsetsController.setRequestedVisibleTypes(0, ime());
+ // Changes the animation state. This also notifies RootView of changed insets, which
+ // causes it to reset its scrollY to 0f (animated) if it was panned
+ mInsetsController.onAnimationStateChanged(ime(), /*running*/ true);
}
if (mStartRootScrollY != 0 && !triggerBack) {
// This causes RootView to update its scroll back to the panned position
@@ -228,12 +235,6 @@
// the IME away
mInsetsController.getHost().getInputMethodManager()
.notifyImeHidden(mInsetsController.getHost().getWindowToken(), statsToken);
-
- // requesting IME as invisible during post-commit
- mInsetsController.setRequestedVisibleTypes(0, ime());
- // Changes the animation state. This also notifies RootView of changed insets, which causes
- // it to reset its scrollY to 0f (animated) if it was panned
- mInsetsController.onAnimationStateChanged(ime(), /*running*/ true);
}
private void reset() {
@@ -254,8 +255,18 @@
}
private boolean isBackAnimationAllowed() {
- // back animation is allowed in all cases except when softInputMode is adjust_resize AND
- // there is no app-registered WindowInsetsAnimationCallback AND edge-to-edge is not enabled.
+
+ if (mViewRoot.mContext.getResources().getConfiguration().windowConfiguration
+ .getWindowingMode() == WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW) {
+ // TODO(b/346726115) enable predictive back animation in multi-window mode in
+ // DisplayImeController
+ return false;
+ }
+
+ // otherwise, the predictive back animation is allowed in all cases except when
+ // 1. softInputMode is adjust_resize AND
+ // 2. there is no app-registered WindowInsetsAnimationCallback AND
+ // 3. edge-to-edge is not enabled.
return (mViewRoot.mWindowAttributes.softInputMode & SOFT_INPUT_MASK_ADJUST)
!= SOFT_INPUT_ADJUST_RESIZE
|| (mViewRoot.mView != null && mViewRoot.mView.hasWindowInsetsAnimationCallback())
diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java
index 83ff88b..1b3b3eb 100644
--- a/core/java/android/view/InsetsAnimationThreadControlRunner.java
+++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java
@@ -89,7 +89,7 @@
SyncRtSurfaceTransactionApplier.SurfaceParams surfaceParams = params[i];
applyParams(t, surfaceParams, mTmpFloat9);
}
- t.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
+ t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
t.apply();
t.close();
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 02ea6d4..df2af73 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -29,6 +29,7 @@
import static android.view.WindowInsets.Type.ime;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+import static com.android.window.flags.Flags.insetsControlSeq;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -890,7 +891,9 @@
@InsetsType int visibleTypes = 0;
@InsetsType int[] cancelledUserAnimationTypes = {0};
for (int i = 0, size = newState.sourceSize(); i < size; i++) {
- final InsetsSource source = newState.sourceAt(i);
+ final InsetsSource source = insetsControlSeq()
+ ? new InsetsSource(newState.sourceAt(i))
+ : newState.sourceAt(i);
@InsetsType int type = source.getType();
@AnimationType int animationType = getAnimationType(type);
final InsetsSourceConsumer consumer = mSourceConsumers.get(source.getId());
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 6a92fd9..c73cbc6 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -28,6 +28,7 @@
import static android.view.InsetsSourceConsumerProto.TYPE_NUMBER;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+import static com.android.window.flags.Flags.insetsControlSeq;
import android.annotation.IntDef;
import android.annotation.Nullable;
@@ -410,7 +411,9 @@
// Frame is changing while animating. Keep note of the new frame but keep existing frame
// until animation is finished.
- newSource = new InsetsSource(newSource);
+ if (!insetsControlSeq()) {
+ newSource = new InsetsSource(newSource);
+ }
mPendingFrame = new Rect(newSource.getFrame());
mPendingVisibleFrame = newSource.getVisibleFrame() != null
? new Rect(newSource.getVisibleFrame())
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index f653524..634469d 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -72,7 +72,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
-import com.android.internal.util.VirtualRefBasePtr;
import com.android.window.flags.Flags;
import dalvik.system.CloseGuard;
@@ -273,10 +272,12 @@
String windowName, int displayId);
private static native void nativeSetFrameTimelineVsync(long transactionObj,
long frameTimelineVsyncId);
- private static native void nativeAddJankDataListener(long nativeListener,
- long nativeSurfaceControl);
- private static native void nativeRemoveJankDataListener(long nativeListener);
- private static native long nativeCreateJankDataListenerWrapper(OnJankDataListener listener);
+ private static native long nativeCreateJankDataListenerWrapper(
+ long surfaceControl, OnJankDataListener listener);
+ private static native long nativeGetJankDataListenerWrapperFinalizer();
+ private static native void nativeAddJankDataListener(long nativeListener);
+ private static native void nativeFlushJankData(long nativeListener);
+ private static native void nativeRemoveJankDataListener(long nativeListener, long afterVsync);
private static native int nativeGetGPUContextPriority();
private static native void nativeSetTransformHint(long nativeObject,
@SurfaceControl.BufferTransform int transformHint);
@@ -461,17 +462,63 @@
* @see #addJankDataListener
* @hide
*/
- public static abstract class OnJankDataListener {
- private final VirtualRefBasePtr mNativePtr;
-
- public OnJankDataListener() {
- mNativePtr = new VirtualRefBasePtr(nativeCreateJankDataListenerWrapper(this));
- }
-
+ public interface OnJankDataListener {
/**
* Called when new jank classifications are available.
*/
- public abstract void onJankDataAvailable(JankData[] jankStats);
+ void onJankDataAvailable(JankData[] jankData);
+
+ }
+
+ /**
+ * Handle to a registered {@link OnJankDatalistener}.
+ * @hide
+ */
+ public static class OnJankDataListenerRegistration {
+ private final long mNativeObject;
+
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ OnJankDataListenerRegistration.class.getClassLoader(),
+ nativeGetJankDataListenerWrapperFinalizer());
+
+ private final Runnable mFreeNativeResources;
+ private boolean mRemoved = false;
+
+ OnJankDataListenerRegistration(SurfaceControl surface, OnJankDataListener listener) {
+ mNativeObject = nativeCreateJankDataListenerWrapper(surface.mNativeObject, listener);
+ mFreeNativeResources = (mNativeObject == 0) ? () -> {} :
+ sRegistry.registerNativeAllocation(this, mNativeObject);
+ }
+
+ /**
+ * Request a flush of any pending jank classification data. May cause the registered
+ * listener to be invoked inband.
+ */
+ public void flush() {
+ nativeFlushJankData(mNativeObject);
+ }
+
+ /**
+ * Request the removal of the registered listener after the VSync with the provided ID. Use
+ * a value <= 0 for afterVsync to remove the listener immediately. The given listener will
+ * not be removed before the given VSync, but may still reveive data for frames past the
+ * provided VSync.
+ */
+ public void removeAfter(long afterVsync) {
+ mRemoved = true;
+ nativeRemoveJankDataListener(mNativeObject, afterVsync);
+ }
+
+ /**
+ * Free the native resources associated with the listener registration.
+ */
+ public void release() {
+ if (!mRemoved) {
+ removeAfter(0);
+ }
+ mFreeNativeResources.run();
+ }
}
private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -2632,19 +2679,11 @@
}
/**
- * Adds a callback to be informed about SF's jank classification for a specific surface.
+ * Adds a callback to be informed about SF's jank classification for this surface.
* @hide
*/
- public static void addJankDataListener(OnJankDataListener listener, SurfaceControl surface) {
- nativeAddJankDataListener(listener.mNativePtr.get(), surface.mNativeObject);
- }
-
- /**
- * Removes a jank callback previously added with {@link #addJankDataListener}
- * @hide
- */
- public static void removeJankDataListener(OnJankDataListener listener) {
- nativeRemoveJankDataListener(listener.mNativePtr.get());
+ public OnJankDataListenerRegistration addJankDataListener(OnJankDataListener listener) {
+ return new OnJankDataListenerRegistration(this, listener);
}
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8c3390c..766e02b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13859,6 +13859,11 @@
})
@ResolvedLayoutDir
public int getLayoutDirection() {
+ final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
+ if (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
+ return LAYOUT_DIRECTION_RESOLVED_DEFAULT;
+ }
return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ==
PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
}
@@ -33933,6 +33938,11 @@
float velocity = mFrameContentVelocity;
final float frameRate = mPreferredFrameRate;
ViewParent parent = mParent;
+ boolean isInputMethodWindowType = false;
+ if (mAttachInfo != null && mAttachInfo.mViewRootImpl != null) {
+ isInputMethodWindowType =
+ mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD;
+ }
if (velocity <= 0 && Float.isNaN(frameRate)) {
// The most common case is when nothing is set, so this special case is called
// often.
@@ -33942,7 +33952,8 @@
|| mLastFrameTop != mTop)
&& viewRootImpl.shouldCheckFrameRate(false)
&& parent instanceof View
- && ((View) parent).mFrameContentVelocity <= 0) {
+ && ((View) parent).mFrameContentVelocity <= 0
+ && !isInputMethodWindowType) {
viewRootImpl.votePreferredFrameRate(MAX_FRAME_RATE, FRAME_RATE_COMPATIBILITY_GTE);
}
if (viewRootImpl.shouldCheckFrameRateCategory()) {
@@ -33965,6 +33976,7 @@
|| mLastFrameTop != mTop)
&& mParent instanceof View
&& ((View) mParent).mFrameContentVelocity <= 0
+ && !isInputMethodWindowType
) {
// This current calculation is very simple. If something on the screen
// moved, then it votes for the highest velocity.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1494d21..88dc3f4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -22,6 +22,8 @@
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
import static android.os.Trace.TRACE_TAG_VIEW;
+import static android.util.SequenceUtils.getInitSeq;
+import static android.util.SequenceUtils.isIncomingSeqNewer;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.DragEvent.ACTION_DRAG_LOCATION;
@@ -112,6 +114,7 @@
import static android.view.accessibility.Flags.forceInvertColor;
import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
import static android.view.flags.Flags.addSchandleToVriSurface;
+import static android.view.flags.Flags.disableDrawWakeLock;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.flags.Flags.sensitiveContentPrematureProtectionRemovedFix;
import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly;
@@ -128,6 +131,7 @@
import static com.android.window.flags.Flags.activityWindowInfoFlag;
import static com.android.window.flags.Flags.enableBufferTransformHintFromDisplay;
import static com.android.window.flags.Flags.insetsControlChangedItem;
+import static com.android.window.flags.Flags.insetsControlSeq;
import static com.android.window.flags.Flags.setScPropertiesInClient;
import android.Manifest;
@@ -146,6 +150,8 @@
import android.app.WindowConfiguration;
import android.app.compat.CompatChanges;
import android.app.servertransaction.WindowStateTransactionItem;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ClipData;
import android.content.ClipDescription;
@@ -178,6 +184,7 @@
import android.graphics.RenderNode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
+import android.hardware.SyncFence;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.display.DisplayManagerGlobal;
@@ -220,6 +227,7 @@
import android.view.InputDevice.InputSourceClass;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl.Transaction;
+import android.view.SurfaceControl.TransactionStats;
import android.view.View.AttachInfo;
import android.view.View.FocusDirection;
import android.view.View.MeasureSpec;
@@ -295,6 +303,7 @@
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* The top of a view hierarchy, implementing the needed protocol between View
@@ -331,6 +340,15 @@
private static final int LOGTAG_VIEWROOT_DRAW_EVENT = 60004;
/**
+ * This change disables the {@code DRAW_WAKE_LOCK}, an internal wakelock acquired per-frame
+ * duration display DOZE. It was added to allow animation during AOD. This wakelock consumes
+ * battery severely if the animation is too heavy, so, it will be removed.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ private static final long DISABLE_DRAW_WAKE_LOCK = 349153669L;
+
+ /**
* Set to false if we do not want to use the multi threaded renderer even though
* threaded renderer (aka hardware renderering) is used. Note that by disabling
* this, WindowCallbacks will not fire.
@@ -889,6 +907,12 @@
/** Non-{@code null} if {@link #mActivityConfigCallback} is not {@code null}. */
@Nullable
private ActivityWindowInfo mLastReportedActivityWindowInfo;
+ @Nullable
+ private final ClientWindowFrames mLastReportedFrames = insetsControlSeq()
+ ? new ClientWindowFrames()
+ : null;
+ private int mLastReportedInsetsStateSeq = getInitSeq();
+ private int mLastReportedActiveControlsSeq = getInitSeq();
boolean mScrollMayChange;
@SoftInputModeFlags
@@ -1104,6 +1128,8 @@
private boolean mIsFrameRateBoosting = false;
// Used to check if it is in touch boosting period.
private boolean mIsTouchBoosting = false;
+ // Used to track if an ongoing press gesture is occurring.
+ private boolean mIsPressedGesture = false;
private boolean mDrawnThisFrame = false;
// Used to check if there is a conflict between different frame rate voting.
// Take 24 and 30 as an example, 24 is not a divisor of 30.
@@ -1185,6 +1211,13 @@
private String mFpsTraceName;
private String mLargestViewTraceName;
+ private final boolean mAppStartInfoTimestampsFlagValue;
+ @GuardedBy("this")
+ private boolean mAppStartTimestampsSent = false;
+ private boolean mAppStartTrackingStarted = false;
+ private long mRenderThreadDrawStartTimeNs = -1;
+ private long mFirstFramePresentedTimeNs = -1;
+
private static boolean sToolkitSetFrameRateReadOnlyFlagValue;
private static boolean sToolkitFrameRateFunctionEnablingReadOnlyFlagValue;
private static boolean sToolkitMetricsForFrameRateDecisionFlagValue;
@@ -1250,7 +1283,6 @@
mDensity = context.getResources().getDisplayMetrics().densityDpi;
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
mFallbackEventHandler = new PhoneFallbackEventHandler(context);
- // TODO(b/222696368): remove getSfInstance usage and use vsyncId for transactions
mChoreographer = Choreographer.getInstance();
mInsetsController = new InsetsController(new ViewRootInsetsControllerHost(this));
mImeBackAnimationController = new ImeBackAnimationController(this, mInsetsController);
@@ -1302,6 +1334,8 @@
} else {
mSensitiveContentProtectionService = null;
}
+
+ mAppStartInfoTimestampsFlagValue = android.app.Flags.appStartInfoTimestamps();
}
public static void addFirstDrawHandler(Runnable callback) {
@@ -1583,8 +1617,6 @@
attachedFrame = null;
}
if (mTranslator != null) {
- mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
- mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls.get());
mTranslator.translateRectInScreenToAppWindow(attachedFrame);
}
mTmpFrames.attachedFrame = attachedFrame;
@@ -1607,8 +1639,7 @@
mAttachInfo.mAlwaysConsumeSystemBars =
(res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS) != 0;
mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars;
- mInsetsController.onStateChanged(mTempInsets);
- mInsetsController.onControlsChanged(mTempControls.get());
+ handleInsetsControlChanged(mTempInsets, mTempControls);
final InsetsState state = mInsetsController.getState();
final Rect displayCutoutSafe = mTempRect;
state.getDisplayCutoutSafe(displayCutoutSafe);
@@ -2206,17 +2237,18 @@
return;
}
+ onClientWindowFramesChanged(frames);
+
CompatibilityInfo.applyOverrideScaleIfNeeded(mergedConfiguration);
final Rect frame = frames.frame;
final Rect displayFrame = frames.displayFrame;
final Rect attachedFrame = frames.attachedFrame;
if (mTranslator != null) {
- mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
mTranslator.translateRectInScreenToAppWindow(frame);
mTranslator.translateRectInScreenToAppWindow(displayFrame);
mTranslator.translateRectInScreenToAppWindow(attachedFrame);
}
- mInsetsController.onStateChanged(insetsState);
+ onInsetsStateChanged(insetsState);
final float compatScale = frames.compatScale;
final boolean frameChanged = !mWinFrame.equals(frame);
final boolean shouldReportActivityWindowInfoChanged =
@@ -2281,26 +2313,69 @@
}
/** Handles messages {@link #MSG_INSETS_CONTROL_CHANGED}. */
- private void handleInsetsControlChanged(@NonNull InsetsState insetsState,
+ @VisibleForTesting
+ public void handleInsetsControlChanged(@NonNull InsetsState insetsState,
@NonNull InsetsSourceControl.Array activeControls) {
- final InsetsSourceControl[] controls = activeControls.get();
-
- if (mTranslator != null) {
- mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
- mTranslator.translateSourceControlsInScreenToAppWindow(controls);
- }
-
// Deliver state change before control change, such that:
// a) When gaining control, controller can compare with server state to evaluate
// whether it needs to run animation.
// b) When loosing control, controller can restore server state by taking last
// dispatched state as truth.
- mInsetsController.onStateChanged(insetsState);
- if (mAdded) {
- mInsetsController.onControlsChanged(controls);
- } else {
- activeControls.release();
+ onInsetsStateChanged(insetsState);
+ onActiveControlsChanged(activeControls);
+ }
+
+ private void onClientWindowFramesChanged(@NonNull ClientWindowFrames inOutFrames) {
+ if (mLastReportedFrames == null) {
+ return;
}
+ if (isIncomingSeqNewer(mLastReportedFrames.seq, inOutFrames.seq)) {
+ // Keep track of the latest.
+ mLastReportedFrames.setTo(inOutFrames);
+ } else {
+ // If the last reported frames is newer, use the last reported instead.
+ inOutFrames.setTo(mLastReportedFrames);
+ }
+ }
+
+ private void onInsetsStateChanged(@NonNull InsetsState insetsState) {
+ if (insetsControlSeq()) {
+ if (isIncomingSeqNewer(mLastReportedInsetsStateSeq, insetsState.getSeq())) {
+ mLastReportedInsetsStateSeq = insetsState.getSeq();
+ } else {
+ // The last reported InsetsState is newer. Skip.
+ return;
+ }
+ }
+
+ if (mTranslator != null) {
+ mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
+ }
+ mInsetsController.onStateChanged(insetsState);
+ }
+
+ private void onActiveControlsChanged(@NonNull InsetsSourceControl.Array activeControls) {
+ if (!mAdded) {
+ // Do not update the last report if window is not added yet.
+ activeControls.release();
+ return;
+ }
+
+ if (insetsControlSeq()) {
+ if (isIncomingSeqNewer(mLastReportedActiveControlsSeq, activeControls.getSeq())) {
+ mLastReportedActiveControlsSeq = activeControls.getSeq();
+ } else {
+ // The last reported controls is newer. Skip.
+ activeControls.release();
+ return;
+ }
+ }
+
+ final InsetsSourceControl[] controls = activeControls.get();
+ if (mTranslator != null) {
+ mTranslator.translateSourceControlsInScreenToAppWindow(controls);
+ }
+ mInsetsController.onControlsChanged(controls);
}
private final DisplayListener mDisplayListener = new DisplayListener() {
@@ -2396,8 +2471,15 @@
}
void pokeDrawLockIfNeeded() {
- if (!Display.isDozeState(mAttachInfo.mDisplayState)) {
- // Only need to acquire wake lock for DOZE state.
+ // Disable DRAW_WAKE_LOCK starting U. Otherwise, only need to acquire it for DOZE state.
+ if (CompatChanges.isChangeEnabled(DISABLE_DRAW_WAKE_LOCK) && disableDrawWakeLock()) {
+ return;
+ }
+
+ if (mAttachInfo.mDisplayState != Display.STATE_DOZE) {
+ // In DOZE_SUSPEND, Android shouldn't control the display; therefore we only poke the
+ // draw wake lock when display state is DOZE. Noted that Display#isDozeState includes
+ // DOZE_SUSPEND as well, so, it's not feasible here.
return;
}
if (mWindowAttributes.type != WindowManager.LayoutParams.TYPE_BASE_APPLICATION) {
@@ -2577,6 +2659,12 @@
notifySurfaceDestroyed();
}
destroySurface();
+
+ // Reset so they can be sent again for warm starts.
+ mAppStartTimestampsSent = false;
+ mAppStartTrackingStarted = false;
+ mRenderThreadDrawStartTimeNs = -1;
+ mFirstFramePresentedTimeNs = -1;
}
}
}
@@ -4375,6 +4463,30 @@
reportDrawFinished(t, seqId);
}
});
+
+ // Only trigger once per {@link ViewRootImpl} instance, so don't add listener if
+ // {link mTransactionCompletedTimeNs} has already been set.
+ if (mAppStartInfoTimestampsFlagValue && !mAppStartTrackingStarted) {
+ mAppStartTrackingStarted = true;
+ Transaction transaction = new Transaction();
+ transaction.addTransactionCompletedListener(mSimpleExecutor,
+ new Consumer<TransactionStats>() {
+ @Override
+ public void accept(TransactionStats transactionStats) {
+ SyncFence presentFence = transactionStats.getPresentFence();
+ if (presentFence.awaitForever()) {
+ if (mFirstFramePresentedTimeNs == -1) {
+ // Only trigger once per {@link ViewRootImpl} instance.
+ mFirstFramePresentedTimeNs = presentFence.getSignalTime();
+ maybeSendAppStartTimes();
+ }
+ }
+ presentFence.close();
+ }
+ });
+ applyTransactionOnDraw(transaction);
+ }
+
if (DEBUG_BLAST) {
Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName());
}
@@ -4382,6 +4494,45 @@
mWmsRequestSyncGroup.add(this, null /* runnable */);
}
+ private void maybeSendAppStartTimes() {
+ synchronized (this) {
+ if (mAppStartTimestampsSent) {
+ // Don't send timestamps more than once.
+ return;
+ }
+
+ // If we already have {@link mRenderThreadDrawStartTimeNs} then pass it through, if not
+ // post to main thread and check if we have it there.
+ if (mRenderThreadDrawStartTimeNs != -1) {
+ sendAppStartTimesLocked();
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (ViewRootImpl.this) {
+ if (mRenderThreadDrawStartTimeNs == -1) {
+ return;
+ }
+ sendAppStartTimesLocked();
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @GuardedBy("this")
+ private void sendAppStartTimesLocked() {
+ try {
+ ActivityManager.getService().reportStartInfoViewTimestamps(
+ mRenderThreadDrawStartTimeNs, mFirstFramePresentedTimeNs);
+ mAppStartTimestampsSent = true;
+ } catch (RemoteException e) {
+ // Ignore, timestamps may be lost.
+ if (DBG) Log.d(TAG, "Exception attempting to report start timestamps.", e);
+ }
+ }
+
/**
* Helper used to notify the service to block projection when a sensitive
* view (the view displays sensitive content) is attached to the window.
@@ -5568,7 +5719,13 @@
registerCallbackForPendingTransactions();
}
+ long timeNs = SystemClock.uptimeNanos();
mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
+
+ // Only trigger once per {@link ViewRootImpl} instance.
+ if (mAppStartInfoTimestampsFlagValue && mRenderThreadDrawStartTimeNs == -1) {
+ mRenderThreadDrawStartTimeNs = timeNs;
+ }
} else {
// If we get here with a disabled & requested hardware renderer, something went
// wrong (an invalidate posted right before we destroyed the hardware surface
@@ -6826,6 +6983,7 @@
setPreferredFrameRate(mPreferredFrameRate);
setPreferredFrameRateCategory(mPreferredFrameRateCategory);
mInvalidationIdleMessagePosted = false;
+ mIsPressedGesture = false;
} else {
mInvalidationIdleMessagePosted = true;
mHandler.sendEmptyMessageDelayed(MSG_CHECK_INVALIDATION_IDLE,
@@ -7312,6 +7470,10 @@
@Override
protected int onProcess(QueuedInputEvent q) {
+ if (q.forPreImeOnly()) {
+ // this event is intended for the ViewPreImeInputStage only, let's forward
+ return FORWARD;
+ }
if (q.mEvent instanceof KeyEvent) {
final KeyEvent keyEvent = (KeyEvent) q.mEvent;
@@ -7839,6 +8001,9 @@
private int processPointerEvent(QueuedInputEvent q) {
final MotionEvent event = (MotionEvent)q.mEvent;
final int action = event.getAction();
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mIsPressedGesture = false;
+ }
boolean handled = false;
if (!disableHandwritingInitiatorForIme()
|| mWindowAttributes.type != TYPE_INPUT_METHOD) {
@@ -7869,6 +8034,9 @@
mWindowAttributes.type)) {
// set the frame rate to the maximum value.
mIsTouchBoosting = true;
+ if (action == MotionEvent.ACTION_DOWN) {
+ mIsPressedGesture = true;
+ }
setPreferredFrameRateCategory(mLastPreferredFrameRateCategory);
}
/**
@@ -9173,6 +9341,8 @@
mRelayoutSeq, mLastSyncSeqId, mRelayoutResult);
mRelayoutRequested = true;
+ onClientWindowFramesChanged(mTmpFrames);
+
if (activityWindowInfoFlag() && mPendingActivityWindowInfo != null) {
final ActivityWindowInfo outInfo = mRelayoutResult.activityWindowInfo;
if (outInfo != null) {
@@ -9189,13 +9359,10 @@
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame);
- mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
- mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls.get());
}
mInvCompatScale = 1f / mTmpFrames.compatScale;
CompatibilityInfo.applyOverrideScaleIfNeeded(mPendingMergedConfiguration);
- mInsetsController.onStateChanged(mTempInsets);
- mInsetsController.onControlsChanged(mTempControls.get());
+ handleInsetsControlChanged(mTempInsets, mTempControls);
mPendingAlwaysConsumeSystemBars =
(relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
@@ -12971,7 +13138,7 @@
if (frameRate <= 0) {
return;
}
- if (frameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE) {
+ if (frameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE && !mIsPressedGesture) {
mIsTouchBoosting = false;
mIsFrameRateBoosting = false;
if (!sToolkitFrameRateVelocityMappingReadOnlyFlagValue) {
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index 199a69a..5b1c7d5 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -256,6 +256,21 @@
"ignore_relayout_auth_pending";
/**
+ * Fixes to handle apps relaying out, and causing problems for autofill.
+ *
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_ENABLE_RELAYOUT = "enable_relayout";
+
+ /**
+ * Enable relative location of views for fingerprinting for relayout.
+ *
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_ENABLE_RELATIVE_LOCATION_FOR_RELAYOUT =
+ "enable_relative_location_for_relayout";
+
+ /**
* Bugfix flag, Autofill should only fill in value from current session.
*
* See frameworks/base/services/autofill/bugfixes.aconfig#fill_fields_from_current_session_only
@@ -543,6 +558,22 @@
false);
}
+ /** @hide */
+ public static boolean enableRelayoutFixes() {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_AUTOFILL,
+ DEVICE_CONFIG_ENABLE_RELAYOUT,
+ true);
+ }
+
+ /** @hide */
+ public static boolean enableRelativeLocationForRelayout() {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_AUTOFILL,
+ DEVICE_CONFIG_ENABLE_RELATIVE_LOCATION_FOR_RELAYOUT,
+ false);
+ }
+
/** @hide **/
public static boolean shouldFillFieldsFromCurrentSessionOnly() {
return DeviceConfig.getBoolean(
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 0d4c556..515ed0e 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -748,7 +748,16 @@
// Controls logic around apps changing some properties of their views when activity loses
// focus due to autofill showing biometric activity, password manager, or password breach check.
- private boolean mRelayoutFix;
+ // Deprecated. TODO: Remove it after ramp of new solution.
+ private boolean mRelayoutFixDeprecated;
+
+ // Controls logic around apps changing some properties of their views when activity loses
+ // focus due to autofill showing biometric activity, password manager, or password breach check.
+ private final boolean mRelayoutFix;
+
+ // Controls logic around apps changing some properties of their views when activity loses
+ // focus due to autofill showing biometric activity, password manager, or password breach check.
+ private final boolean mRelativePositionForRelayout;
// Indicates whether the credman integration is enabled.
private final boolean mIsCredmanIntegrationEnabled;
@@ -978,11 +987,31 @@
mShouldIncludeInvisibleViewInAssistStructure =
AutofillFeatureFlags.shouldIncludeInvisibleViewInAssistStructure();
- mRelayoutFix = AutofillFeatureFlags.shouldIgnoreRelayoutWhenAuthPending();
+ mRelayoutFixDeprecated = AutofillFeatureFlags.shouldIgnoreRelayoutWhenAuthPending();
+ mRelayoutFix = AutofillFeatureFlags.enableRelayoutFixes();
+ mRelativePositionForRelayout = AutofillFeatureFlags.enableRelativeLocationForRelayout();
mIsCredmanIntegrationEnabled = Flags.autofillCredmanIntegration();
}
/**
+ * Whether to apply relayout fixes.
+ *
+ * @hide
+ */
+ public boolean isRelayoutFixEnabled() {
+ return mRelayoutFix;
+ }
+
+ /**
+ * Whether to use relative positions and locations of the views for disambiguation.
+ *
+ * @hide
+ */
+ public boolean isRelativePositionForRelayoutEnabled() {
+ return mRelativePositionForRelayout;
+ }
+
+ /**
* Whether to apply heuristic check on important views before triggering fill request
*
* @hide
@@ -1779,7 +1808,7 @@
}
return;
}
- if (mRelayoutFix && mState == STATE_PENDING_AUTHENTICATION) {
+ if (mRelayoutFixDeprecated && mState == STATE_PENDING_AUTHENTICATION) {
if (sVerbose) {
Log.v(TAG, "notifyViewVisibilityChanged(): ignoring in auth pending mode");
}
@@ -2917,7 +2946,7 @@
Intent fillInIntent, boolean authenticateInline) {
synchronized (mLock) {
if (sessionId == mSessionId) {
- if (mRelayoutFix) {
+ if (mRelayoutFixDeprecated) {
mState = STATE_PENDING_AUTHENTICATION;
}
final AutofillClient client = getClient();
@@ -3778,7 +3807,7 @@
@GuardedBy("mLock")
private boolean isPendingAuthenticationLocked() {
- return mRelayoutFix && mState == STATE_PENDING_AUTHENTICATION;
+ return mRelayoutFixDeprecated && mState == STATE_PENDING_AUTHENTICATION;
}
@GuardedBy("mLock")
@@ -4322,6 +4351,13 @@
addToSet(mInvisibleDialogTrackedIds, id);
}
}
+ } else {
+ if (sDebug) {
+ // isClientVisibleForAutofillLocked() is checking whether
+ // activity has stopped under the hood
+ Log.d(TAG, "notifyViewVisibilityChangedLocked(): ignoring "
+ + "view visibility change since activity has stopped");
+ }
}
if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
diff --git a/core/java/android/view/autofill/OWNERS b/core/java/android/view/autofill/OWNERS
index 898947a..7f3b4e5 100644
--- a/core/java/android/view/autofill/OWNERS
+++ b/core/java/android/view/autofill/OWNERS
@@ -1,10 +1,11 @@
# Bug component: 351486
-simranjit@google.com
haoranzhang@google.com
+jiewenlei@google.com
+simranjit@google.com
skxu@google.com
+shuc@google.com
yunicorn@google.com
-reemabajwa@google.com
# Bug component: 543785 = per-file *Augmented*
per-file *Augmented* = wangqi@google.com
diff --git a/core/java/android/view/flags/view_flags.aconfig b/core/java/android/view/flags/view_flags.aconfig
index 4d4e4af..f570a9a 100644
--- a/core/java/android/view/flags/view_flags.aconfig
+++ b/core/java/android/view/flags/view_flags.aconfig
@@ -89,4 +89,12 @@
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ name: "disable_draw_wake_lock"
+ namespace: "wear_frameworks"
+ description: "Disable Draw Wakelock starting U."
+ bug: "331698645"
+ is_fixed_read_only: true
}
\ No newline at end of file
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 21d6184..9512347 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -62,6 +62,7 @@
import android.content.res.loader.ResourcesLoader;
import android.content.res.loader.ResourcesProvider;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.BlendMode;
import android.graphics.Outline;
import android.graphics.PorterDuff;
@@ -90,6 +91,7 @@
import android.util.IntArray;
import android.util.Log;
import android.util.LongArray;
+import android.util.LongSparseArray;
import android.util.Pair;
import android.util.SizeF;
import android.util.SparseArray;
@@ -98,6 +100,7 @@
import android.util.TypedValue.ComplexDimensionUnit;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoStream;
import android.util.proto.ProtoUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
@@ -1266,11 +1269,16 @@
int intentId = in.readInt();
String intentUri = in.readString8();
RemoteCollectionItems items = new RemoteCollectionItems(in, currentRootData);
- mIdToUriMapping.put(intentId, intentUri);
- mUriToCollectionMapping.put(intentUri, items);
+ addMapping(intentId, intentUri, items);
}
}
+ void addMapping(int intentId, String intentUri, RemoteCollectionItems items) {
+ mIdToUriMapping.put(intentId, intentUri);
+ mUriToCollectionMapping.put(intentUri, items);
+ }
+
+
void setHierarchyDataForId(int intentId, HierarchyRootData data) {
String uri = mIdToUriMapping.get(intentId);
if (mUriToCollectionMapping.get(uri) == null) {
@@ -1465,6 +1473,87 @@
mUriToCollectionMapping.get(intentUri).writeToParcel(out, flags, true);
}
}
+
+ public void writeToProto(Context context, ProtoOutputStream out) {
+ final long token = out.start(RemoteViewsProto.REMOTE_COLLECTION_CACHE);
+ for (int i = 0; i < mIdToUriMapping.size(); i++) {
+ final long entryToken = out.start(RemoteViewsProto.RemoteCollectionCache.ENTRIES);
+ out.write(RemoteViewsProto.RemoteCollectionCache.Entry.ID,
+ mIdToUriMapping.keyAt(i));
+ String intentUri = mIdToUriMapping.valueAt(i);
+ out.write(RemoteViewsProto.RemoteCollectionCache.Entry.URI, intentUri);
+ final long itemsToken = out.start(
+ RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS);
+ mUriToCollectionMapping.get(intentUri).writeToProto(context, out, /* attached= */
+ true);
+ out.end(itemsToken);
+ out.end(entryToken);
+ }
+ out.end(token);
+ }
+ }
+
+ private PendingResources<RemoteCollectionCache> populateRemoteCollectionCacheFromProto(
+ ProtoInputStream in) throws Exception {
+ final ArrayList<LongSparseArray<Object>> entries = new ArrayList<>();
+ final long token = in.start(RemoteViewsProto.REMOTE_COLLECTION_CACHE);
+ while (in.nextField() != NO_MORE_FIELDS) {
+ switch (in.getFieldNumber()) {
+ case (int) RemoteViewsProto.RemoteCollectionCache.ENTRIES:
+ final LongSparseArray<Object> entry = new LongSparseArray<>();
+ final long entryToken = in.start(
+ RemoteViewsProto.RemoteCollectionCache.ENTRIES);
+ while (in.nextField() != NO_MORE_FIELDS) {
+ switch (in.getFieldNumber()) {
+ case (int) RemoteViewsProto.RemoteCollectionCache.Entry.ID:
+ entry.put(RemoteViewsProto.RemoteCollectionCache.Entry.ID,
+ in.readInt(
+ RemoteViewsProto.RemoteCollectionCache.Entry.ID));
+ break;
+ case (int) RemoteViewsProto.RemoteCollectionCache.Entry.URI:
+ entry.put(RemoteViewsProto.RemoteCollectionCache.Entry.URI,
+ in.readString(
+ RemoteViewsProto.RemoteCollectionCache.Entry.URI));
+ break;
+ case (int) RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS:
+ final long itemsToken = in.start(
+ RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS);
+ entry.put(RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS,
+ RemoteCollectionItems.createFromProto(in));
+ in.end(itemsToken);
+ break;
+ default:
+ Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+ + ProtoUtils.currentFieldToString(in));
+ }
+ }
+ in.end(entryToken);
+ checkContainsKeys(entry,
+ new long[]{RemoteViewsProto.RemoteCollectionCache.Entry.ID,
+ RemoteViewsProto.RemoteCollectionCache.Entry.URI,
+ RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS});
+ entries.add(entry);
+ break;
+ default:
+ Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+ + ProtoUtils.currentFieldToString(in));
+ }
+ }
+ in.end(token);
+
+ return (context, resources, rootData, depth) -> {
+ for (LongSparseArray<Object> entry : entries) {
+ int id = (int) entry.get(RemoteViewsProto.RemoteCollectionCache.Entry.ID);
+ String uri = (String) entry.get(RemoteViewsProto.RemoteCollectionCache.Entry.URI);
+ // Depth resets to 0 for RemoteCollectionItems
+ RemoteCollectionItems items = ((PendingResources<RemoteCollectionItems>) entry.get(
+ RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS)).create(context,
+ resources, rootData, depth);
+ rootData.mRemoteCollectionCache.addMapping(id, uri, items);
+ }
+ // Redundant return, but type signature requires we return something.
+ return rootData.mRemoteCollectionCache;
+ };
}
private class SetRemoteViewsAdapterIntent extends Action {
@@ -2080,6 +2169,15 @@
dest.writeTypedList(mBitmaps, flags);
}
+ public void writeBitmapsToProto(ProtoOutputStream out) {
+ for (int i = 0; i < mBitmaps.size(); i++) {
+ final Bitmap bitmap = mBitmaps.get(i);
+ final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.WEBP_LOSSLESS, 100, bytes);
+ out.write(RemoteViewsProto.BITMAP_CACHE, bytes.toByteArray());
+ }
+ }
+
public int getBitmapMemory() {
if (mBitmapMemory < 0) {
mBitmapMemory = 0;
@@ -7522,6 +7620,127 @@
dest.restoreAllowSquashing(prevAllowSquashing);
}
+ /** @hide */
+ public void writeToProto(Context context, ProtoOutputStream out) {
+ writeToProto(context, out, /* attached= */ false);
+ }
+
+ private void writeToProto(Context context, ProtoOutputStream out, boolean attached) {
+ for (long id : mIds) {
+ out.write(RemoteViewsProto.RemoteCollectionItems.IDS, id);
+ }
+
+ boolean restoreRoot = false;
+ out.write(RemoteViewsProto.RemoteCollectionItems.ATTACHED, attached);
+ if (!attached && mViews.length > 0 && !mViews[0].mIsRoot) {
+ restoreRoot = true;
+ mViews[0].mIsRoot = true;
+ }
+ for (RemoteViews view : mViews) {
+ final long viewsToken = out.start(RemoteViewsProto.RemoteCollectionItems.VIEWS);
+ view.writePreviewToProto(context, out);
+ out.end(viewsToken);
+ }
+ if (restoreRoot) mViews[0].mIsRoot = false;
+ out.write(RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS, mHasStableIds);
+ out.write(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT, mViewTypeCount);
+ }
+
+ /**
+ * Overload used for testing unattached RemoteCollectionItems serialization.
+ *
+ * @hide
+ */
+ public static RemoteCollectionItems createFromProto(Context context, ProtoInputStream in)
+ throws Exception {
+ return createFromProto(in).create(context, context.getResources(), /* rootData= */
+ null, 0);
+ }
+
+ /** @hide */
+ public static PendingResources<RemoteCollectionItems> createFromProto(ProtoInputStream in)
+ throws Exception {
+ final LongSparseArray<Object> values = new LongSparseArray<>();
+ values.put(RemoteViewsProto.RemoteCollectionItems.IDS, new ArrayList<Long>());
+ values.put(RemoteViewsProto.RemoteCollectionItems.VIEWS,
+ new ArrayList<PendingResources<RemoteViews>>());
+ while (in.nextField() != NO_MORE_FIELDS) {
+ switch (in.getFieldNumber()) {
+ case (int) RemoteViewsProto.RemoteCollectionItems.IDS:
+ ((ArrayList<Long>) values.get(
+ RemoteViewsProto.RemoteCollectionItems.IDS)).add(
+ in.readLong(RemoteViewsProto.RemoteCollectionItems.IDS));
+ break;
+ case (int) RemoteViewsProto.RemoteCollectionItems.VIEWS:
+ final long viewsToken = in.start(
+ RemoteViewsProto.RemoteCollectionItems.VIEWS);
+ ((ArrayList<PendingResources<RemoteViews>>) values.get(
+ RemoteViewsProto.RemoteCollectionItems.VIEWS)).add(
+ RemoteViews.createFromProto(in));
+ in.end(viewsToken);
+ break;
+ case (int) RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS:
+ values.put(RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS,
+ in.readBoolean(
+ RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS));
+ break;
+ case (int) RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT:
+ values.put(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT,
+ in.readInt(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT));
+ break;
+ case (int) RemoteViewsProto.RemoteCollectionItems.ATTACHED:
+ values.put(RemoteViewsProto.RemoteCollectionItems.ATTACHED,
+ in.readBoolean(RemoteViewsProto.RemoteCollectionItems.ATTACHED));
+ break;
+ default:
+ Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+ + ProtoUtils.currentFieldToString(in));
+ }
+ }
+
+ checkContainsKeys(values,
+ new long[]{RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT});
+ return (context, resources, rootData, depth) -> {
+ List<Long> idList = (List<Long>) values.get(
+ RemoteViewsProto.RemoteCollectionItems.IDS);
+ long[] ids = new long[idList.size()];
+ for (int i = 0; i < idList.size(); i++) {
+ ids[i] = idList.get(i);
+ }
+ boolean attached = (boolean) values.get(
+ RemoteViewsProto.RemoteCollectionItems.ATTACHED, false);
+ List<PendingResources<RemoteViews>> pendingViews =
+ (List<PendingResources<RemoteViews>>) values.get(
+ RemoteViewsProto.RemoteCollectionItems.VIEWS);
+ RemoteViews[] views = new RemoteViews[pendingViews.size()];
+
+ if (attached && rootData == null) {
+ throw new IllegalStateException("Cannot create a RemoteCollectionItems from "
+ + "proto that was attached without providing HierarchyRootData");
+ }
+
+ int firstChildIndex = 0;
+ if (!attached && pendingViews.size() > 0) {
+ // If written as unattached, get HierarchyRootData from first view
+ views[0] = pendingViews.get(0).create(context, resources, /* rootData= */ null,
+ /* depth= */ 0);
+ rootData = views[0].getHierarchyRootData();
+ firstChildIndex = 1;
+ }
+ for (int i = firstChildIndex; i < views.length; i++) {
+ // Depth is reset to 0 for RemoteCollectionItems item views, see Parcel
+ // constructor.
+ views[i] = pendingViews.get(i).create(context, resources, rootData,
+ /* depth= */ 0);
+ }
+ return new RemoteCollectionItems(ids, views,
+ (boolean) values.get(RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS,
+ false),
+ (int) values.get(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT,
+ 0));
+ };
+ }
+
/**
* Returns the id for {@code position}. See {@link #hasStableIds()} for whether this id
* should be considered meaningful across collection updates.
@@ -7907,6 +8126,10 @@
if (mViewId != 0 && mViewId != -1) {
out.write(RemoteViewsProto.VIEW_ID, appResources.getResourceName(mViewId));
}
+ if (mIsRoot) {
+ mBitmapCache.writeBitmapsToProto(out);
+ mCollectionCache.writeToProto(context, out);
+ }
out.write(RemoteViewsProto.IS_ROOT, mIsRoot);
out.write(RemoteViewsProto.APPLY_FLAGS, mApplyFlags);
out.write(RemoteViewsProto.HAS_DRAW_INSTRUCTIONS, mHasDrawInstructions);
@@ -7968,6 +8191,7 @@
final List<PendingResources<RemoteViews>> mSizedRemoteViews = new ArrayList<>();
PendingResources<RemoteViews> mLandscapeViews = null;
PendingResources<RemoteViews> mPortraitViews = null;
+ PendingResources<RemoteCollectionCache> mPopulateRemoteCollectionCache = null;
boolean mIsRoot = false;
boolean mHasDrawInstructions = false;
};
@@ -8018,6 +8242,18 @@
ref.mPortraitViews = createFromProto(in);
in.end(portraitToken);
break;
+ case (int) RemoteViewsProto.BITMAP_CACHE:
+ byte[] src = in.readBytes(RemoteViewsProto.BITMAP_CACHE);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(src, 0, src.length);
+ ref.mRv.mBitmapCache.getBitmapId(bitmap);
+ break;
+ case (int) RemoteViewsProto.REMOTE_COLLECTION_CACHE:
+ final long collectionToken = in.start(
+ RemoteViewsProto.REMOTE_COLLECTION_CACHE);
+ ref.mPopulateRemoteCollectionCache =
+ ref.mRv.populateRemoteCollectionCacheFromProto(in);
+ in.end(collectionToken);
+ break;
case (int) RemoteViewsProto.IS_ROOT:
ref.mIsRoot = in.readBoolean(RemoteViewsProto.IS_ROOT);
break;
@@ -8087,6 +8323,9 @@
rv.setLightBackgroundLayoutId(lightBackgroundLayoutId);
}
}
+ if (ref.mPopulateRemoteCollectionCache != null) {
+ ref.mPopulateRemoteCollectionCache.create(context, resources, rootData, depth);
+ }
if (ref.mProviderInstanceId != -1) {
rv.mProviderInstanceId = ref.mProviderInstanceId;
}
@@ -8139,6 +8378,16 @@
}
}
+ private static void checkContainsKeys(LongSparseArray<?> array, long[] requiredFields) {
+ for (long requiredField : requiredFields) {
+ if (array.indexOfKey(requiredField) < 0) {
+ throw new IllegalArgumentException(
+ "RemoteViews proto missing field: " + ProtoStream.getFieldIdString(
+ requiredField));
+ }
+ }
+ }
+
private static SizeF createSizeFFromProto(ProtoInputStream in) throws Exception {
float width = 0;
float height = 0;
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 4fb6e69..9b87e23 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -489,7 +489,8 @@
return;
}
OnBackAnimationCallback animationCallback = getBackAnimationCallback();
- if (animationCallback != null) {
+ if (animationCallback != null
+ && !(callback instanceof ImeBackAnimationController)) {
mProgressAnimator.onBackInvoked(callback::onBackInvoked);
} else {
mProgressAnimator.reset();
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 69cac6f..94f6503 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -56,3 +56,11 @@
description: "Improved metrics."
bug: "339245692"
}
+
+flag {
+ name: "bal_send_intent_with_options"
+ namespace: "responsible_apis"
+ description: "Add options parameter to IntentSender.sendIntent."
+ bug: "339720406"
+}
+
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 8cd2a3e..ae9d757 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -93,16 +93,6 @@
flag {
namespace: "windowing_sdk"
- name: "always_defer_transition_when_apply_wct"
- description: "Report error when defer transition fails when it should not"
- bug: "335562144"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
- namespace: "windowing_sdk"
name: "fix_pip_restore_to_overlay"
description: "Restore exit-pip activity back to ActivityEmbedding overlay"
bug: "297887697"
@@ -181,3 +171,14 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ namespace: "windowing_sdk"
+ name: "per_user_display_window_settings"
+ description: "Whether to store display window settings per user to avoid conflicts"
+ bug: "346668297"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
index 6420620..a3fcfad 100644
--- a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
+++ b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
@@ -72,6 +72,7 @@
UserShortcutType.TRIPLETAP,
UserShortcutType.TWOFINGER_DOUBLETAP,
UserShortcutType.QUICK_SETTINGS,
+ UserShortcutType.GESTURE
})
public @interface UserShortcutType {
int DEFAULT = 0;
@@ -81,6 +82,7 @@
int TRIPLETAP = 1 << 2;
int TWOFINGER_DOUBLETAP = 1 << 3;
int QUICK_SETTINGS = 1 << 4;
+ int GESTURE = 1 << 5;
// LINT.ThenChange(:shortcut_type_array)
}
@@ -95,6 +97,7 @@
UserShortcutType.TRIPLETAP,
UserShortcutType.TWOFINGER_DOUBLETAP,
UserShortcutType.QUICK_SETTINGS,
+ UserShortcutType.GESTURE
// LINT.ThenChange(:shortcut_type_intdef)
};
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
index c8d6194..01cbb55 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
@@ -20,6 +20,7 @@
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityButtonLongPressStatus;
@@ -66,6 +67,9 @@
NAV_BAR_MODE_GESTURAL == getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode);
+ final int targetType = (isGestureNavigateEnabled
+ && android.provider.Flags.a11yStandaloneGestureEnabled()) ? GESTURE : SOFTWARE;
+
if (isGestureNavigateEnabled) {
final TextView promptPrologue = findViewById(R.id.accessibility_button_prompt_prologue);
promptPrologue.setText(isTouchExploreOn
@@ -78,7 +82,7 @@
: R.string.accessibility_gesture_instructional_text);
}
- mTargets.addAll(getTargets(this, SOFTWARE));
+ mTargets.addAll(getTargets(this, targetType));
final GridView gridview = findViewById(R.id.accessibility_button_chooser_grid);
gridview.setAdapter(new ButtonTargetAdapter(mTargets));
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
index 6256dbc..44c7543 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
@@ -18,7 +18,6 @@
import static com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
-import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getInstalledTargets;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import static com.android.internal.accessibility.util.AccessibilityUtils.isUserSetupCompleted;
@@ -213,10 +212,7 @@
final boolean isEditMenuMode =
mTargetAdapter.getShortcutMenuMode() == ShortcutMenuMode.EDIT;
final int selectDialogTitleId = R.string.accessibility_select_shortcut_menu_title;
- final int editDialogTitleId =
- mShortcutType == SOFTWARE
- ? R.string.accessibility_edit_shortcut_menu_button_title
- : R.string.accessibility_edit_shortcut_menu_volume_title;
+ final int editDialogTitleId = R.string.accessibility_edit_shortcut_menu_volume_title;
mMenuDialog.setTitle(getString(isEditMenuMode ? editDialogTitleId : selectDialogTitleId));
mMenuDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
index ec90dd2..a753110 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
@@ -16,6 +16,7 @@
package com.android.internal.accessibility.dialog;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.internal.accessibility.util.ShortcutUtils.optInValueToSettings;
@@ -197,6 +198,9 @@
@VisibleForTesting
public static boolean isRecognizedShortcutType(@UserShortcutType int shortcutType) {
int mask = SOFTWARE | HARDWARE;
+ if (android.provider.Flags.a11yStandaloneGestureEnabled()) {
+ mask = mask | GESTURE;
+ }
return (shortcutType != 0 && (shortcutType & mask) == shortcutType);
}
}
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
index 8e18f84..9d66461 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
@@ -23,6 +23,7 @@
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
@@ -247,6 +248,8 @@
} else {
return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
}
+ case GESTURE:
+ return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE;
case HARDWARE:
return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
case QUICK_SETTINGS:
diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
index 6b0ca9f..48f86ff 100644
--- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
+++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
@@ -166,6 +166,8 @@
switch (type) {
case UserShortcutType.SOFTWARE:
return Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
+ case UserShortcutType.GESTURE:
+ return Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS;
case UserShortcutType.HARDWARE:
return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
case UserShortcutType.TRIPLETAP:
@@ -190,6 +192,7 @@
public static int convertToType(String key) {
return switch (key) {
case Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS -> UserShortcutType.SOFTWARE;
+ case Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS -> UserShortcutType.GESTURE;
case Settings.Secure.ACCESSIBILITY_QS_TARGETS -> UserShortcutType.QUICK_SETTINGS;
case Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE -> UserShortcutType.HARDWARE;
case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED ->
diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java
index 0068490..9f5ed65 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -78,9 +78,9 @@
// Feature flag that will eventually be removed
private final boolean mIntRangeUserPerceptionEnabled;
- public BrightnessSynchronizer(Context context, boolean intRangeUserPerceptionEnabled) {
- this(context, Looper.getMainLooper(), SystemClock::uptimeMillis,
- intRangeUserPerceptionEnabled);
+ public BrightnessSynchronizer(Context context, Looper looper,
+ boolean intRangeUserPerceptionEnabled) {
+ this(context, looper, SystemClock::uptimeMillis, intRangeUserPerceptionEnabled);
}
@VisibleForTesting
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index 618f622..1638699 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -160,8 +160,24 @@
*/
public static final int CUJ_DESKTOP_MODE_RESIZE_WINDOW = 106;
+ /** Track entering desktop mode interaction. */
+ public static final int CUJ_DESKTOP_MODE_ENTER_MODE = 107;
+
+ /** Track exiting desktop mode interaction. */
+ public static final int CUJ_DESKTOP_MODE_EXIT_MODE = 108;
+
+ /** Track minimize window interaction in desktop mode. */
+ public static final int CUJ_DESKTOP_MODE_MINIMIZE_WINDOW = 109;
+
+ /** Track window drag interaction in desktop mode. */
+ public static final int CUJ_DESKTOP_MODE_DRAG_WINDOW = 110;
+
+ /** Track launching a dialog from a status bar chip. */
+ public static final int CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP = 111;
+
+
// When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
- @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_RESIZE_WINDOW;
+ @VisibleForTesting static final int LAST_CUJ = CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP;
/** @hide */
@IntDef({
@@ -259,7 +275,12 @@
CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK,
CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW,
CUJ_FOLD_ANIM,
- CUJ_DESKTOP_MODE_RESIZE_WINDOW
+ CUJ_DESKTOP_MODE_RESIZE_WINDOW,
+ CUJ_DESKTOP_MODE_ENTER_MODE,
+ CUJ_DESKTOP_MODE_EXIT_MODE,
+ CUJ_DESKTOP_MODE_MINIMIZE_WINDOW,
+ CUJ_DESKTOP_MODE_DRAG_WINDOW,
+ CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {}
@@ -368,6 +389,11 @@
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MAXIMIZE_WINDOW;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_FOLD_ANIM] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__FOLD_ANIM;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_RESIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_RESIZE_WINDOW;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_MODE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_MODE;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_EXIT_MODE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_EXIT_MODE;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MINIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MINIMIZE_WINDOW;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_DRAG_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_DRAG_WINDOW;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP;
}
private Cuj() {
@@ -576,6 +602,16 @@
return "FOLD_ANIM";
case CUJ_DESKTOP_MODE_RESIZE_WINDOW:
return "DESKTOP_MODE_RESIZE_WINDOW";
+ case CUJ_DESKTOP_MODE_ENTER_MODE:
+ return "DESKTOP_MODE_ENTER_MODE";
+ case CUJ_DESKTOP_MODE_EXIT_MODE:
+ return "DESKTOP_MODE_EXIT_MODE";
+ case CUJ_DESKTOP_MODE_MINIMIZE_WINDOW:
+ return "DESKTOP_MODE_MINIMIZE_WINDOW";
+ case CUJ_DESKTOP_MODE_DRAG_WINDOW:
+ return "DESKTOP_MODE_DRAG_WINDOW";
+ case CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP:
+ return "STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 86729f7..bf5df03 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -63,8 +63,8 @@
* A class that allows the app to get the frame metrics from HardwareRendererObserver.
* @hide
*/
-public class FrameTracker extends SurfaceControl.OnJankDataListener
- implements HardwareRendererObserver.OnFrameMetricsAvailableListener {
+public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvailableListener,
+ SurfaceControl.OnJankDataListener {
private static final String TAG = "FrameTracker";
private static final long INVALID_ID = -1;
@@ -118,6 +118,7 @@
public final boolean mSurfaceOnly;
private SurfaceControl mSurfaceControl;
+ private SurfaceControl.OnJankDataListenerRegistration mJankDataListenerRegistration;
private long mBeginVsyncId = INVALID_ID;
private long mEndVsyncId = INVALID_ID;
private boolean mMetricsFinalized;
@@ -316,7 +317,8 @@
Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, name, name, (int) mBeginVsyncId);
markEvent("FT#beginVsync", mBeginVsyncId);
markEvent("FT#layerId", mSurfaceControl.getLayerId());
- mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
+ mJankDataListenerRegistration =
+ mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
if (!mSurfaceOnly) {
mRendererWrapper.addObserver(mObserver);
}
@@ -342,6 +344,10 @@
markEvent("FT#endVsync", mEndVsyncId);
Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, name, (int) mBeginVsyncId);
+ if (mJankDataListenerRegistration != null) {
+ mJankDataListenerRegistration.removeAfter(mEndVsyncId);
+ }
+
// We don't remove observer here,
// will remove it when all the frame metrics in this duration are called back.
// See onFrameMetricsAvailable for the logic of removing the observer.
@@ -358,6 +364,9 @@
// Send a flush jank data transaction.
if (mSurfaceControl != null && mSurfaceControl.isValid()) {
SurfaceControl.Transaction.sendSurfaceFlushJankData(mSurfaceControl);
+ if (mJankDataListenerRegistration != null) {
+ mJankDataListenerRegistration.flush();
+ }
}
long delay;
@@ -680,7 +689,10 @@
@VisibleForTesting
@UiThread
public void removeObservers() {
- mSurfaceControlWrapper.removeJankStatsListener(this);
+ if (mJankDataListenerRegistration != null) {
+ mJankDataListenerRegistration.release();
+ mJankDataListenerRegistration = null;
+ }
if (!mSurfaceOnly) {
// HWUI part.
mRendererWrapper.removeObserver(mObserver);
@@ -796,14 +808,10 @@
}
public static class SurfaceControlWrapper {
-
- public void addJankStatsListener(SurfaceControl.OnJankDataListener listener,
- SurfaceControl surfaceControl) {
- SurfaceControl.addJankDataListener(listener, surfaceControl);
- }
-
- public void removeJankStatsListener(SurfaceControl.OnJankDataListener listener) {
- SurfaceControl.removeJankDataListener(listener);
+ /** adds the jank listener to the given surface */
+ public SurfaceControl.OnJankDataListenerRegistration addJankStatsListener(
+ SurfaceControl.OnJankDataListener listener, SurfaceControl surfaceControl) {
+ return surfaceControl.addJankDataListener(listener);
}
}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index b86cbfb..33610a0 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -325,6 +325,48 @@
/**
* Begins a trace session.
*
+ * @param surface a handle for the surface to begin tracing for.
+ * @param context context to provide display and handler information.
+ * @param cujType the specific {@link Cuj.CujType}.
+ * @return boolean true if the tracker is started successfully, false otherwise.
+ */
+ public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType) {
+ try {
+ return begin(Configuration.Builder.withSurface(cujType, context, surface));
+ } catch (IllegalArgumentException ex) {
+ Log.d(TAG, "Build configuration failed!", ex);
+ return false;
+ }
+ }
+
+ /**
+ * Begins a trace session.
+ *
+ * @param surface a handle for the surface to begin tracing for.
+ * @param context context to provide display and handler information.
+ * @param cujType the specific {@link Cuj.CujType}.
+ * @param tag a tag containing extra information about the interaction.
+ * @return boolean true if the tracker is started successfully, false otherwise.
+ */
+ public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType,
+ String tag) {
+ try {
+ final Configuration.Builder builder =
+ Configuration.Builder.withSurface(cujType, context, surface);
+ if (!TextUtils.isEmpty(tag)) {
+ builder.setTag(tag);
+ }
+ return begin(builder);
+ } catch (IllegalArgumentException ex) {
+ Log.d(TAG, "Build configuration failed!", ex);
+ return false;
+ }
+ }
+
+
+ /**
+ * Begins a trace session.
+ *
* @param builder the builder of the configurations for instrumenting the CUJ.
* @return boolean true if the tracker is begun successfully, false otherwise.
*/
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 66b2a9c..238e6f5 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -75,10 +75,11 @@
/** @hide */
public class TransitionAnimation {
public static final int WALLPAPER_TRANSITION_NONE = 0;
- public static final int WALLPAPER_TRANSITION_OPEN = 1;
- public static final int WALLPAPER_TRANSITION_CLOSE = 2;
- public static final int WALLPAPER_TRANSITION_INTRA_OPEN = 3;
- public static final int WALLPAPER_TRANSITION_INTRA_CLOSE = 4;
+ public static final int WALLPAPER_TRANSITION_CHANGE = 1;
+ public static final int WALLPAPER_TRANSITION_OPEN = 2;
+ public static final int WALLPAPER_TRANSITION_CLOSE = 3;
+ public static final int WALLPAPER_TRANSITION_INTRA_OPEN = 4;
+ public static final int WALLPAPER_TRANSITION_INTRA_CLOSE = 5;
// These are the possible states for the enter/exit activities during a thumbnail transition
private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
diff --git a/core/java/com/android/internal/protolog/common/ProtoLog.java b/core/java/com/android/internal/protolog/ProtoLog.java
similarity index 94%
rename from core/java/com/android/internal/protolog/common/ProtoLog.java
rename to core/java/com/android/internal/protolog/ProtoLog.java
index 8149cd5..0118c05 100644
--- a/core/java/com/android/internal/protolog/common/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/ProtoLog.java
@@ -14,7 +14,11 @@
* limitations under the License.
*/
-package com.android.internal.protolog.common;
+package com.android.internal.protolog;
+
+import com.android.internal.protolog.common.IProtoLog;
+import com.android.internal.protolog.common.IProtoLogGroup;
+import com.android.internal.protolog.common.LogLevel;
/**
* ProtoLog API - exposes static logging methods. Usage of this API is similar
@@ -35,7 +39,9 @@
* Methods in this class are stubs, that are replaced by optimised versions by the ProtoLogTool
* during build.
*/
+// LINT.IfChange
public class ProtoLog {
+// LINT.ThenChange(frameworks/base/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt)
// Needs to be set directly otherwise the protologtool tries to transform the method call
public static boolean REQUIRE_PROTOLOGTOOL = true;
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 8236783..511c680 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -109,4 +109,5 @@
boolean isWeakEscrowTokenActive(long handle, int userId);
boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId);
void unlockUserKeyIfUnsecured(int userId);
+ boolean writeRepairModeCredential(int userId);
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e46b8d7..f4ad487 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -449,6 +449,21 @@
}
/**
+ * Save the current password data to the repair mode file.
+ *
+ * @return true if success or false otherwise.
+ */
+ public boolean writeRepairModeCredential(int userId) {
+ throwIfCalledOnMainThread();
+ try {
+ return getLockSettings().writeRepairModeCredential(userId);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Failed to write repair mode credential", re);
+ return false;
+ }
+ }
+
+ /**
* Check to see if a credential matches the saved one.
* If credential matches, return an opaque attestation that the challenge was verified.
*
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 00262be..5c2a167 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -15,6 +15,7 @@
*/
package com.android.internal.widget.remotecompose.core;
+import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
import com.android.internal.widget.remotecompose.core.operations.Theme;
@@ -308,9 +309,10 @@
/**
* Returns true if x,y coordinate is within bounds
+ *
* @param x x-coordinate
* @param y y-coordinate
- * @return x,y coordinate is within bounds
+ * @return x, y coordinate is within bounds
*/
public boolean contains(float x, float y) {
return x >= mLeft && x < mRight
@@ -483,6 +485,37 @@
return builder.toString();
}
+ /**
+ * Gets the names of all named colors.
+ *
+ * @return array of named colors or null
+ */
+ public String[] getNamedColors() {
+ int count = 0;
+ for (Operation op : mOperations) {
+ if (op instanceof NamedVariable) {
+ NamedVariable n = (NamedVariable) op;
+ if (n.mVarType == NamedVariable.COLOR_TYPE) {
+ count++;
+ }
+ }
+ }
+ if (count == 0) {
+ return null;
+ }
+ String[] ret = new String[count];
+ int i = 0;
+ for (Operation op : mOperations) {
+ if (op instanceof NamedVariable) {
+ NamedVariable n = (NamedVariable) op;
+ if (n.mVarType == NamedVariable.COLOR_TYPE) {
+ ret[i++] = n.mVarName;
+ }
+ }
+ }
+ return ret;
+ }
+
//////////////////////////////////////////////////////////////////////////
// Painting
//////////////////////////////////////////////////////////////////////////
@@ -493,6 +526,7 @@
/**
* Returns > 0 if it needs to repaint
+ *
* @return
*/
public int needsRepaint() {
@@ -525,7 +559,6 @@
context.loadFloat(RemoteContext.ID_WINDOW_WIDTH, getWidth());
context.loadFloat(RemoteContext.ID_WINDOW_HEIGHT, getHeight());
mRepaintNext = context.updateOps();
-
for (Operation op : mOperations) {
// operations will only be executed if no theme is set (ie UNSPECIFIED)
// or the theme is equal as the one passed in argument to paint.
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index 4b45ab6..fc8668e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -19,6 +19,7 @@
import com.android.internal.widget.remotecompose.core.operations.ClickArea;
import com.android.internal.widget.remotecompose.core.operations.ClipPath;
import com.android.internal.widget.remotecompose.core.operations.ClipRect;
+import com.android.internal.widget.remotecompose.core.operations.ColorConstant;
import com.android.internal.widget.remotecompose.core.operations.ColorExpression;
import com.android.internal.widget.remotecompose.core.operations.DrawArc;
import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
@@ -42,6 +43,7 @@
import com.android.internal.widget.remotecompose.core.operations.MatrixScale;
import com.android.internal.widget.remotecompose.core.operations.MatrixSkew;
import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
+import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.PaintData;
import com.android.internal.widget.remotecompose.core.operations.PathData;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
@@ -105,6 +107,8 @@
public static final int COLOR_EXPRESSIONS = 134;
public static final int TEXT_FROM_FLOAT = 135;
public static final int TEXT_MERGE = 136;
+ public static final int NAMED_VARIABLE = 137;
+ public static final int COLOR_CONSTANT = 138;
/////////////////////////////////////////======================
public static IntMap<CompanionOperation> map = new IntMap<>();
@@ -147,7 +151,8 @@
map.put(COLOR_EXPRESSIONS, ColorExpression.COMPANION);
map.put(TEXT_FROM_FLOAT, TextFromFloat.COMPANION);
map.put(TEXT_MERGE, TextMerge.COMPANION);
-
+ map.put(NAMED_VARIABLE, NamedVariable.COMPANION);
+ map.put(COLOR_CONSTANT, ColorConstant.COMPANION);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index 52fc314..d462c7d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -19,6 +19,7 @@
import com.android.internal.widget.remotecompose.core.operations.ClickArea;
import com.android.internal.widget.remotecompose.core.operations.ClipPath;
import com.android.internal.widget.remotecompose.core.operations.ClipRect;
+import com.android.internal.widget.remotecompose.core.operations.ColorConstant;
import com.android.internal.widget.remotecompose.core.operations.ColorExpression;
import com.android.internal.widget.remotecompose.core.operations.DrawArc;
import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
@@ -42,6 +43,7 @@
import com.android.internal.widget.remotecompose.core.operations.MatrixScale;
import com.android.internal.widget.remotecompose.core.operations.MatrixSkew;
import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
+import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.PaintData;
import com.android.internal.widget.remotecompose.core.operations.PathData;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
@@ -899,6 +901,20 @@
}
/**
+ * Add a simple color
+ * @param color
+ * @return id that represents that color
+ */
+ public int addColor(int color) {
+ ColorConstant c = new ColorConstant(0, color);
+ short id = (short) mRemoteComposeState.cache(c);
+ c.mColorId = id;
+ c.write(mBuffer);
+ return id;
+ }
+
+
+ /**
* Add a color that represents the tween between two colors
* @param color1
* @param color2
@@ -1013,5 +1029,14 @@
return FloatAnimation.packToFloatArray(duration, type, spec, initialValue, wrap);
}
+ /**
+ * This defines the name of the color given the id.
+ * @param id of the color
+ * @param name Name of the color
+ */
+ public void setColorName(int id, String name) {
+ NamedVariable.COMPANION.apply(mBuffer, id,
+ NamedVariable.COLOR_TYPE, name);
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
index 66a37e67..bfe67c8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
@@ -33,11 +33,13 @@
public class RemoteComposeState {
public static final int START_ID = 42;
private static final int MAX_FLOATS = 500;
+ private static final int MAX_COLORS = 200;
private final IntMap<Object> mIntDataMap = new IntMap<>();
private final IntMap<Boolean> mIntWrittenMap = new IntMap<>();
private final HashMap<Object, Integer> mDataIntMap = new HashMap();
private final float[] mFloatMap = new float[MAX_FLOATS]; // efficient cache
- private final int[] mColorMap = new int[MAX_FLOATS]; // efficient cache
+ private final int[] mColorMap = new int[MAX_COLORS]; // efficient cache
+ private final boolean[] mColorOverride = new boolean[MAX_COLORS];
private int mNextId = START_ID;
{
@@ -49,6 +51,7 @@
/**
* Get Object based on id. The system will cache things like bitmaps
* Paths etc. They can be accessed with this command
+ *
* @param id
* @return
*/
@@ -58,6 +61,7 @@
/**
* true if the cache contain this id
+ *
* @param id
* @return
*/
@@ -150,9 +154,32 @@
* @param color
*/
public void updateColor(int id, int color) {
+ if (mColorOverride[id]) {
+ return;
+ }
mColorMap[id] = color;
}
+ /**
+ * Adds a colorOverride.
+ * This is a list of ids and there colors optimized for playback;
+ *
+ * @param id
+ * @param color
+ */
+ public void overrideColor(int id, int color) {
+ mColorOverride[id] = true;
+ mColorMap[id] = color;
+ }
+
+ /**
+ * Clear the color Overrides
+ */
+ public void clearColorOverride() {
+ for (int i = 0; i < mColorOverride.length; i++) {
+ mColorOverride[i] = false;
+ }
+ }
/**
* Method to determine if a cached value has been written to the documents WireBuffer based on
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index 7e72168..32027d8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -72,6 +72,14 @@
return (System.nanoTime() - mStart) * 1E-9f;
}
+ /**
+ * Set the value of a named Color.
+ * This overrides the color in the document
+ * @param colorName
+ * @param color
+ */
+ public abstract void setNamedColorOverride(String colorName, int color);
+
/**
* The context can be used in a few different mode, allowing operations to skip being executed:
@@ -262,16 +270,45 @@
public static final int ID_COMPONENT_WIDTH = 7;
public static final int ID_COMPONENT_HEIGHT = 8;
public static final int ID_CALENDAR_MONTH = 9;
+ public static final int ID_OFFSET_TO_UTC = 10;
+ public static final int ID_WEEK_DAY = 11;
+ public static final int ID_DAY_OF_MONTH = 12;
+ /**
+ * CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600
+ */
public static final float FLOAT_CONTINUOUS_SEC = Utils.asNan(ID_CONTINUOUS_SEC);
+ /**
+ * seconds run from Midnight=0 quantized to seconds hour 0..3599
+ */
public static final float FLOAT_TIME_IN_SEC = Utils.asNan(ID_TIME_IN_SEC);
+ /**
+ * minutes run from Midnight=0 quantized to minutes 0..1439
+ */
public static final float FLOAT_TIME_IN_MIN = Utils.asNan(ID_TIME_IN_MIN);
+ /**
+ * hours run from Midnight=0 quantized to Hours 0-23
+ */
public static final float FLOAT_TIME_IN_HR = Utils.asNan(ID_TIME_IN_HR);
+ /**
+ * Moth of Year quantized to MONTHS 1-12. 1 = January
+ */
public static final float FLOAT_CALENDAR_MONTH = Utils.asNan(ID_CALENDAR_MONTH);
+ /**
+ * DAY OF THE WEEK 1-7. 1 = Monday
+ */
+ public static final float FLOAT_WEEK_DAY = Utils.asNan(ID_WEEK_DAY);
+ /**
+ * DAY OF THE MONTH 1-31
+ */
+ public static final float FLOAT_DAY_OF_MONTH = Utils.asNan(ID_DAY_OF_MONTH);
+
public static final float FLOAT_WINDOW_WIDTH = Utils.asNan(ID_WINDOW_WIDTH);
public static final float FLOAT_WINDOW_HEIGHT = Utils.asNan(ID_WINDOW_HEIGHT);
public static final float FLOAT_COMPONENT_WIDTH = Utils.asNan(ID_COMPONENT_WIDTH);
public static final float FLOAT_COMPONENT_HEIGHT = Utils.asNan(ID_COMPONENT_HEIGHT);
+ // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f)
+ public static final float FLOAT_OFFSET_TO_UTC = Utils.asNan(ID_OFFSET_TO_UTC);
///////////////////////////////////////////////////////////////////////////////////////////////
// Click handling
///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
index e9708b7..04e04bbb 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
@@ -16,6 +16,9 @@
package com.android.internal.widget.remotecompose.core;
import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
/**
* This generates the standard system variables for time.
@@ -23,6 +26,7 @@
public class TimeVariables {
/**
* This class populates all time variables in the system
+ *
* @param context
*/
public void updateTime(RemoteContext context) {
@@ -33,19 +37,29 @@
// hours run from Midnight=0 quantized to Hours 0-23
// CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600
// CONTINUOUS_SEC is accurate to milliseconds due to float precession
- int month = dateTime.getDayOfMonth();
+ // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f)
+ int month = dateTime.getMonth().getValue();
int hour = dateTime.getHour();
int minute = dateTime.getMinute();
int seconds = dateTime.getSecond();
int currentMinute = hour * 60 + minute;
int currentSeconds = minute * 60 + seconds;
float sec = currentSeconds + dateTime.getNano() * 1E-9f;
+ int day_week = dateTime.getDayOfWeek().getValue();
+
+ ZoneId zone = ZoneId.systemDefault();
+ OffsetDateTime offsetDateTime = dateTime.atZone(zone).toOffsetDateTime();
+ ZoneOffset offset = offsetDateTime.getOffset();
+
+ context.loadFloat(RemoteContext.ID_OFFSET_TO_UTC, offset.getTotalSeconds());
context.loadFloat(RemoteContext.ID_CONTINUOUS_SEC, sec);
context.loadFloat(RemoteContext.ID_TIME_IN_SEC, currentSeconds);
context.loadFloat(RemoteContext.ID_TIME_IN_MIN, currentMinute);
context.loadFloat(RemoteContext.ID_TIME_IN_HR, hour);
context.loadFloat(RemoteContext.ID_CALENDAR_MONTH, month);
+ context.loadFloat(RemoteContext.ID_DAY_OF_MONTH, month);
+ context.loadFloat(RemoteContext.ID_WEEK_DAY, day_week);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
new file mode 100644
index 0000000..15c208f
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 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.internal.widget.remotecompose.core.operations;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+
+import java.util.List;
+
+/**
+ * Operation that defines a simple Color based on ID
+ * Mainly for colors in theming.
+ */
+public class ColorConstant implements Operation {
+ public int mColorId;
+ public int mColor;
+ public static final Companion COMPANION = new Companion();
+
+ public ColorConstant(int colorId, int color) {
+ this.mColorId = colorId;
+ this.mColor = color;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ COMPANION.apply(buffer, mColorId, mColor);
+ }
+
+ @Override
+ public String toString() {
+ return "ColorConstant[" + mColorId + "] = " + Utils.colorInt(mColor) + "";
+ }
+
+ public static class Companion implements CompanionOperation {
+ private Companion() {
+ }
+
+ @Override
+ public String name() {
+ return "ColorConstant";
+ }
+
+ @Override
+ public int id() {
+ return Operations.COLOR_CONSTANT;
+ }
+
+ /**
+ * Writes out the operation to the buffer
+ *
+ * @param buffer
+ * @param colorId
+ * @param color
+ */
+ public void apply(WireBuffer buffer, int colorId, int color) {
+ buffer.start(Operations.COLOR_CONSTANT);
+ buffer.writeInt(colorId);
+ buffer.writeInt(color);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ int colorId = buffer.readInt();
+ int color = buffer.readInt();
+ operations.add(new ColorConstant(colorId, color));
+ }
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ context.loadColor(mColorId, mColor);
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return indent + toString();
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
index 0c5b286..ae27f5f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
@@ -32,7 +32,9 @@
public int mVarType;
public static final Companion COMPANION = new Companion();
public static final int MAX_STRING_SIZE = 4000;
-
+ public static final int COLOR_TYPE = 2;
+ public static final int FLOAT_TYPE = 1;
+ public static final int STRING_TYPE = 0;
public NamedVariable(int varId, int varType, String name) {
this.mVarId = varId;
this.mVarType = varType;
@@ -72,7 +74,7 @@
* @param text
*/
public void apply(WireBuffer buffer, int varId, int varType, String text) {
- buffer.start(Operations.DATA_TEXT);
+ buffer.start(Operations.NAMED_VARIABLE);
buffer.writeInt(varId);
buffer.writeInt(varType);
buffer.writeUTF8(text);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
index fdc6860..fcb3bfa 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
@@ -78,7 +78,9 @@
*/
public static void log(String str) {
StackTraceElement s = new Throwable().getStackTrace()[1];
- System.out.println("(" + s.getFileName() + ":" + s.getLineNumber() + ")." + str);
+ System.out.println("(" + s.getFileName()
+ + ":" + s.getLineNumber() + "). "
+ + s.getMethodName() + "() " + str);
}
/**
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
index d1c4d46..a42c584 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
@@ -103,5 +103,15 @@
return "Document{\n"
+ mDocument + '}';
}
+
+ /**
+ * Gets a array of Names of the named colors defined in the loaded doc.
+ *
+ * @return
+ */
+ public String[] getNamedColors() {
+ return mDocument.getNamedColors();
+ }
+
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
index 7423a16..73e94fa 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -16,9 +16,11 @@
package com.android.internal.widget.remotecompose.player;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.TypedValue;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
@@ -53,6 +55,7 @@
/**
* Turn on debug information
+ *
* @param debugFlags 1 to set debug on
*/
public void setDebug(int debugFlags) {
@@ -79,6 +82,7 @@
} else {
mInner.setDocument(null);
}
+ mapColors();
}
/**
@@ -106,7 +110,8 @@
LayoutParams.MATCH_PARENT);
addView(horizontalScrollView, layoutParams);
}
- } break;
+ }
+ break;
case RootContentBehavior.SCROLL_VERTICAL: {
if (!(mInner.getParent() instanceof ScrollView)) {
((ViewGroup) mInner.getParent()).removeView(mInner);
@@ -123,9 +128,10 @@
LayoutParams.MATCH_PARENT);
addView(scrollView, layoutParams);
}
- } break;
+ }
+ break;
default:
- if (mInner.getParent() != this) {
+ if (mInner.getParent() != this) {
((ViewGroup) mInner.getParent()).removeView(mInner);
removeAllViews();
LayoutParams layoutParams = new LayoutParams(
@@ -178,5 +184,230 @@
mInner.invalidate();
}
}
+
+ /**
+ * This returns a list of colors that have names in the Document.
+ *
+ * @return
+ */
+ public String[] getNamedColors() {
+ return mInner.getNamedColors();
+ }
+
+ /**
+ * This sets a color based on its name. Overriding the color set in
+ * the document.
+ *
+ * @param colorName Name of the color
+ * @param colorValue The new color value
+ */
+ public void setColor(String colorName, int colorValue) {
+ mInner.setColor(colorName, colorValue);
+ }
+
+ private void mapColors() {
+ String[] name = getNamedColors();
+
+ // make every effort to terminate early
+ if (name == null) {
+ return;
+ }
+ boolean found = false;
+ for (int i = 0; i < name.length; i++) {
+ if (name[i].startsWith("android.")) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return;
+ }
+
+ for (int i = 0; i < name.length; i++) {
+ String s = name[i];
+ if (!s.startsWith("android.")) {
+ continue;
+ }
+ String sub = s.substring("android.".length());
+ switch (sub) {
+ case "actionBarItemBackground":
+ setRColor(s, android.R.attr.actionBarItemBackground);
+ break;
+ case "actionModeBackground":
+ setRColor(s, android.R.attr.actionModeBackground);
+ break;
+ case "actionModeSplitBackground":
+ setRColor(s, android.R.attr.actionModeSplitBackground);
+ break;
+ case "activatedBackgroundIndicator":
+ setRColor(s, android.R.attr.activatedBackgroundIndicator);
+ break;
+ case "colorAccent": // Highlight color for interactive elements
+ setRColor(s, android.R.attr.colorAccent);
+ break;
+ case "colorActivatedHighlight":
+ setRColor(s, android.R.attr.colorActivatedHighlight);
+ break;
+ case "colorBackground": // background color for the app’s window
+ setRColor(s, android.R.attr.colorBackground);
+ break;
+ case "colorBackgroundCacheHint":
+ setRColor(s, android.R.attr.colorBackgroundCacheHint);
+ break;
+ // Background color for floating elements
+ case "colorBackgroundFloating":
+ setRColor(s, android.R.attr.colorBackgroundFloating);
+ break;
+ case "colorButtonNormal": // The default color for buttons
+ setRColor(s, android.R.attr.colorButtonNormal);
+ break;
+ // Color for activated (checked) state of controls.
+ case "colorControlActivated":
+ setRColor(s, android.R.attr.colorControlActivated);
+ break;
+ case "colorControlHighlight": // Color for highlights on controls
+ setRColor(s, android.R.attr.colorControlHighlight);
+ break;
+ // Default color for controls in their normal state.
+ case "colorControlNormal":
+ setRColor(s, android.R.attr.colorControlNormal);
+ break;
+ // Color for edge effects (e.g., overscroll glow)
+ case "colorEdgeEffect":
+ setRColor(s, android.R.attr.colorEdgeEffect);
+ break;
+ case "colorError":
+ setRColor(s, android.R.attr.colorError);
+ break;
+ case "colorFocusedHighlight":
+ setRColor(s, android.R.attr.colorFocusedHighlight);
+ break;
+ case "colorForeground": // General foreground color for views.
+ setRColor(s, android.R.attr.colorForeground);
+ break;
+ // Foreground color for inverse backgrounds.
+ case "colorForegroundInverse":
+ setRColor(s, android.R.attr.colorForegroundInverse);
+ break;
+ case "colorLongPressedHighlight":
+ setRColor(s, android.R.attr.colorLongPressedHighlight);
+ break;
+ case "colorMultiSelectHighlight":
+ setRColor(s, android.R.attr.colorMultiSelectHighlight);
+ break;
+ case "colorPressedHighlight":
+ setRColor(s, android.R.attr.colorPressedHighlight);
+ break;
+ case "colorPrimary": // The primary branding color for the app.
+ setRColor(s, android.R.attr.colorPrimary);
+ break;
+ case "colorPrimaryDark": // darker variant of the primary color
+ setRColor(s, android.R.attr.colorPrimaryDark);
+ break;
+ case "colorSecondary":
+ setRColor(s, android.R.attr.colorSecondary);
+ break;
+ case "detailsElementBackground":
+ setRColor(s, android.R.attr.detailsElementBackground);
+ break;
+ case "editTextBackground":
+ setRColor(s, android.R.attr.editTextBackground);
+ break;
+ case "galleryItemBackground":
+ setRColor(s, android.R.attr.galleryItemBackground);
+ break;
+ case "headerBackground":
+ setRColor(s, android.R.attr.headerBackground);
+ break;
+ case "itemBackground":
+ setRColor(s, android.R.attr.itemBackground);
+ break;
+ case "numbersBackgroundColor":
+ setRColor(s, android.R.attr.numbersBackgroundColor);
+ break;
+ case "panelBackground":
+ setRColor(s, android.R.attr.panelBackground);
+ break;
+ case "panelColorBackground":
+ setRColor(s, android.R.attr.panelColorBackground);
+ break;
+ case "panelFullBackground":
+ setRColor(s, android.R.attr.panelFullBackground);
+ break;
+ case "popupBackground":
+ setRColor(s, android.R.attr.popupBackground);
+ break;
+ case "queryBackground":
+ setRColor(s, android.R.attr.queryBackground);
+ break;
+ case "selectableItemBackground":
+ setRColor(s, android.R.attr.selectableItemBackground);
+ break;
+ case "submitBackground":
+ setRColor(s, android.R.attr.submitBackground);
+ break;
+ case "textColor":
+ setRColor(s, android.R.attr.textColor);
+ break;
+ case "windowBackground":
+ setRColor(s, android.R.attr.windowBackground);
+ break;
+ case "windowBackgroundFallback":
+ setRColor(s, android.R.attr.windowBackgroundFallback);
+ break;
+ // Primary text color for inverse backgrounds
+ case "textColorPrimaryInverse":
+ setRColor(s, android.R.attr.textColorPrimaryInverse);
+ break;
+ // Secondary text color for inverse backgrounds
+ case "textColorSecondaryInverse":
+ setRColor(s, android.R.attr.textColorSecondaryInverse);
+ break;
+ // Tertiary text color for less important text.
+ case "textColorTertiary":
+ setRColor(s, android.R.attr.textColorTertiary);
+ break;
+ // Tertiary text color for inverse backgrounds
+ case "textColorTertiaryInverse":
+ setRColor(s, android.R.attr.textColorTertiaryInverse);
+ break;
+ // Text highlight color (e.g., selected text background).
+ case "textColorHighlight":
+ setRColor(s, android.R.attr.textColorHighlight);
+ break;
+ // Color for hyperlinks.
+ case "textColorLink":
+ setRColor(s, android.R.attr.textColorLink);
+ break;
+ // Color for hint text.
+ case "textColorHint":
+ setRColor(s, android.R.attr.textColorHint);
+ break;
+ // text color for inverse backgrounds..
+ case "textColorHintInverse":
+ setRColor(s, android.R.attr.textColorHintInverse);
+ break;
+ // Default color for the thumb of switches.
+ case "colorSwitchThumbNormal":
+ setRColor(s, android.R.attr.colorControlNormal);
+ break;
+ }
+ }
+ }
+
+ private void setRColor(String name, int id) {
+ int color = getColorFromResource(id);
+ setColor(name, color);
+ }
+
+ private int getColorFromResource(int id) {
+ TypedValue typedValue = new TypedValue();
+ try (TypedArray arr = getContext()
+ .getApplicationContext()
+ .obtainStyledAttributes(typedValue.data, new int[]{id})) {
+ int color = arr.getColor(0, -1);
+ return color;
+ }
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
index 6e4893b..dd43bd5 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
@@ -76,6 +76,16 @@
}
/**
+ * Override a color to force it to be the color provided
+ *
+ * @param colorName name of color
+ * @param color
+ */
+ public void setNamedColorOverride(String colorName, int color) {
+ int id = mVarNameHashMap.get(colorName).mId;
+ mRemoteComposeState.overrideColor(id, color);
+ }
+ /**
* Decode a byte array into an image and cache it using the given imageId
*
* @param width with of image to be loaded
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index 97d23c8..a2f79cc 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -42,6 +42,7 @@
boolean mInActionDown = false;
boolean mDebug = false;
Point mActionDownPoint = new Point(0, 0);
+ AndroidRemoteContext mARContext = new AndroidRemoteContext();
public RemoteComposeCanvas(Context context) {
super(context);
@@ -88,8 +89,6 @@
invalidate();
}
- AndroidRemoteContext mARContext = new AndroidRemoteContext();
-
@Override
public void onViewAttachedToWindow(View view) {
if (mDocument == null) {
@@ -120,6 +119,20 @@
removeAllViews();
}
+ public String[] getNamedColors() {
+ return mDocument.getNamedColors();
+ }
+
+ /**
+ * set the color associated with this name.
+ *
+ * @param colorName Name of color typically "android.xxx"
+ * @param colorValue "the argb value"
+ */
+ public void setColor(String colorName, int colorValue) {
+ mARContext.setNamedColorOverride(colorName, colorValue);
+ }
+
public interface ClickCallbacks {
void click(int id, String metadata);
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 911bb19..011ef30 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -196,6 +196,7 @@
"android_os_PerformanceHintManager.cpp",
"android_os_SELinux.cpp",
"android_os_ServiceManager.cpp",
+ "android_os_ServiceManagerNative.cpp",
"android_os_SharedMemory.cpp",
"android_os_storage_StorageManager.cpp",
"android_os_UEventObserver.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 71d041c..ed59327 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -148,6 +148,7 @@
extern int register_android_os_HwRemoteBinder(JNIEnv *env);
extern int register_android_os_NativeHandle(JNIEnv *env);
extern int register_android_os_ServiceManager(JNIEnv *env);
+extern int register_android_os_ServiceManagerNative(JNIEnv* env);
extern int register_android_os_MessageQueue(JNIEnv* env);
extern int register_android_os_Parcel(JNIEnv* env);
extern int register_android_os_PerformanceHintManager(JNIEnv* env);
@@ -1544,6 +1545,7 @@
REG_JNI(register_android_os_HwRemoteBinder),
REG_JNI(register_android_os_NativeHandle),
REG_JNI(register_android_os_ServiceManager),
+ REG_JNI(register_android_os_ServiceManagerNative),
REG_JNI(register_android_os_storage_StorageManager),
REG_JNI(register_android_service_DataLoaderService),
REG_JNI(register_android_view_DisplayEventReceiver),
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 2316f4c..b8fd3d0 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -17,9 +17,12 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Camera-JNI"
+#include <android/content/AttributionSourceState.h>
+#include <android_os_Parcel.h>
#include <android_runtime/android_graphics_SurfaceTexture.h>
#include <android_runtime/android_view_Surface.h>
#include <binder/IMemory.h>
+#include <binder/Parcel.h>
#include <camera/Camera.h>
#include <camera/StringUtils.h>
#include <cutils/properties.h>
@@ -523,22 +526,45 @@
}
}
-static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz, jint deviceId,
+static bool attributionSourceStateForJavaParcel(JNIEnv *env, jobject jClientAttributionParcel,
+ AttributionSourceState &clientAttribution) {
+ const Parcel *clientAttributionParcel = parcelForJavaObject(env, jClientAttributionParcel);
+ if (clientAttribution.readFromParcel(clientAttributionParcel) != ::android::OK) {
+ jniThrowRuntimeException(env, "Fail to unparcel AttributionSourceState");
+ return false;
+ }
+ clientAttribution.uid = Camera::USE_CALLING_UID;
+ clientAttribution.pid = Camera::USE_CALLING_PID;
+ return true;
+}
+
+static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz,
+ jobject jClientAttributionParcel,
jint devicePolicy) {
- return Camera::getNumberOfCameras(deviceId, devicePolicy);
+ AttributionSourceState clientAttribution;
+ if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) {
+ return 0;
+ }
+ return Camera::getNumberOfCameras(clientAttribution, devicePolicy);
}
static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz, jint cameraId,
- jint rotationOverride, jint deviceId,
+ jint rotationOverride,
+ jobject jClientAttributionParcel,
jint devicePolicy, jobject info_obj) {
+ AttributionSourceState clientAttribution;
+ if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) {
+ return;
+ }
+
CameraInfo cameraInfo;
- if (cameraId >= Camera::getNumberOfCameras(deviceId, devicePolicy) || cameraId < 0) {
+ if (cameraId >= Camera::getNumberOfCameras(clientAttribution, devicePolicy) || cameraId < 0) {
ALOGE("%s: Unknown camera ID %d", __FUNCTION__, cameraId);
jniThrowRuntimeException(env, "Unknown camera ID");
return;
}
- status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, deviceId, devicePolicy,
+ status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, clientAttribution, devicePolicy,
&cameraInfo);
if (rc != NO_ERROR) {
jniThrowRuntimeException(env, "Fail to get camera info");
@@ -557,9 +583,14 @@
// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jint cameraId, jstring clientPackageName,
- jint rotationOverride,
- jboolean forceSlowJpegMode, jint deviceId,
+ jint rotationOverride, jboolean forceSlowJpegMode,
+ jobject jClientAttributionParcel,
jint devicePolicy) {
+ AttributionSourceState clientAttribution;
+ if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) {
+ return -EACCES;
+ }
+
// Convert jstring to String16
const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
env->GetStringChars(clientPackageName, NULL));
@@ -569,10 +600,8 @@
reinterpret_cast<const jchar*>(rawClientName));
int targetSdkVersion = android_get_application_target_sdk_version();
- sp<Camera> camera =
- Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID, Camera::USE_CALLING_PID,
- targetSdkVersion, rotationOverride, forceSlowJpegMode, deviceId,
- devicePolicy);
+ sp<Camera> camera = Camera::connect(cameraId, clientName, targetSdkVersion, rotationOverride,
+ forceSlowJpegMode, clientAttribution, devicePolicy);
if (camera == NULL) {
return -EACCES;
}
@@ -600,7 +629,7 @@
// Update default display orientation in case the sensor is reverse-landscape
CameraInfo cameraInfo;
- status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, deviceId, devicePolicy,
+ status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, clientAttribution, devicePolicy,
&cameraInfo);
if (rc != NO_ERROR) {
ALOGE("%s: getCameraInfo error: %d", __FUNCTION__, rc);
@@ -1056,10 +1085,11 @@
//-------------------------------------------------
static const JNINativeMethod camMethods[] = {
- {"_getNumberOfCameras", "(II)I", (void *)android_hardware_Camera_getNumberOfCameras},
- {"_getCameraInfo", "(IIIILandroid/hardware/Camera$CameraInfo;)V",
+ {"_getNumberOfCameras", "(Landroid/os/Parcel;I)I",
+ (void *)android_hardware_Camera_getNumberOfCameras},
+ {"_getCameraInfo", "(IILandroid/os/Parcel;ILandroid/hardware/Camera$CameraInfo;)V",
(void *)android_hardware_Camera_getCameraInfo},
- {"native_setup", "(Ljava/lang/Object;ILjava/lang/String;IZII)I",
+ {"native_setup", "(Ljava/lang/Object;ILjava/lang/String;IZLandroid/os/Parcel;I)I",
(void *)android_hardware_Camera_native_setup},
{"native_release", "()V", (void *)android_hardware_Camera_release},
{"setPreviewSurface", "(Landroid/view/Surface;)V",
diff --git a/core/jni/android_os_ServiceManagerNative.cpp b/core/jni/android_os_ServiceManagerNative.cpp
new file mode 100644
index 0000000..39a3013
--- /dev/null
+++ b/core/jni/android_os_ServiceManagerNative.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+#include <binder/IServiceManagerFFI.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+
+#include "android_util_Binder.h"
+namespace android {
+
+jobject JNICALL Java_android_os_ServiceManagerProxy_getNativeServiceManager(JNIEnv *env,
+ jobject obj) {
+ sp<IBinder> service = IInterface::asBinder(
+ impl::getJavaServicemanagerImplPrivateDoNotUseExceptInTheOnePlaceItIsUsed());
+ return javaObjectForIBinder(env, service);
+}
+
+// ----------------------------------------------------------------------------
+
+static const JNINativeMethod serviceManagerNativeMethods[] = {
+ /* name, signature, funcPtr */
+ {"getNativeServiceManager", "()Landroid/os/IBinder;",
+ (void *)Java_android_os_ServiceManagerProxy_getNativeServiceManager}};
+
+int register_android_os_ServiceManagerNative(JNIEnv *env) {
+ return jniRegisterNativeMethods(env, "android/os/ServiceManagerProxy",
+ serviceManagerNativeMethods,
+ NELEM(serviceManagerNativeMethods));
+}
+} // namespace android
\ No newline at end of file
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 5365838..9ce7658 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -22,6 +22,7 @@
#include <android/graphics/properties.h>
#include <android/graphics/region.h>
#include <android/gui/BnWindowInfosReportedListener.h>
+#include <android/gui/JankData.h>
#include <android/hardware/display/IDeviceProductInfoConstants.h>
#include <android/os/IInputConstants.h>
#include <android_runtime/AndroidRuntime.h>
@@ -2062,11 +2063,13 @@
env->DeleteWeakGlobalRef(mOnJankDataListenerWeak);
}
- void onJankDataAvailable(const std::vector<JankData>& jankData) {
+ bool onJankDataAvailable(const std::vector<gui::JankData>& jankData) override {
JNIEnv* env = getEnv();
jobject target = env->NewLocalRef(mOnJankDataListenerWeak);
- if (target == nullptr) return;
+ if (target == nullptr) {
+ return false;
+ }
jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(),
gJankDataClassInfo.clazz, nullptr);
@@ -2082,6 +2085,8 @@
jJankDataArray);
env->DeleteLocalRef(jJankDataArray);
env->DeleteLocalRef(target);
+
+ return true;
}
private:
@@ -2096,29 +2101,49 @@
jobject mOnJankDataListenerWeak;
};
-static void nativeAddJankDataListener(JNIEnv* env, jclass clazz,
- jlong jankDataCallbackListenerPtr,
- jlong nativeSurfaceControl) {
+static jlong nativeCreateJankDataListenerWrapper(JNIEnv* env, jclass clazz,
+ jlong nativeSurfaceControl, jobject listener) {
sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(nativeSurfaceControl));
if (surface == nullptr) {
+ return 0;
+ }
+
+ sp<JankDataListenerWrapper> wrapper = sp<JankDataListenerWrapper>::make(env, listener);
+ if (wrapper->addListener(std::move(surface)) != OK) {
+ return 0;
+ }
+
+ wrapper->incStrong((void*)nativeCreateJankDataListenerWrapper);
+ return reinterpret_cast<jlong>(wrapper.get());
+}
+
+static void destroyJankDatalistenerWrapper(void* ptr) {
+ JankDataListenerWrapper* wrapper = reinterpret_cast<JankDataListenerWrapper*>(ptr);
+ if (wrapper == nullptr) {
return;
}
- sp<JankDataListenerWrapper> wrapper =
- reinterpret_cast<JankDataListenerWrapper*>(jankDataCallbackListenerPtr);
- TransactionCompletedListener::getInstance()->addJankListener(wrapper, surface);
+ wrapper->decStrong((void*)nativeCreateJankDataListenerWrapper);
}
-static void nativeRemoveJankDataListener(JNIEnv* env, jclass clazz,
- jlong jankDataCallbackListenerPtr) {
- sp<JankDataListenerWrapper> wrapper =
- reinterpret_cast<JankDataListenerWrapper*>(jankDataCallbackListenerPtr);
- TransactionCompletedListener::getInstance()->removeJankListener(wrapper);
+static jlong nativeGetJankDataListenerWrapperFinalizer() {
+ return reinterpret_cast<jlong>(&destroyJankDatalistenerWrapper);
}
-static jlong nativeCreateJankDataListenerWrapper(JNIEnv* env, jclass clazz,
- jobject jankDataListenerObject) {
- return reinterpret_cast<jlong>(
- new JankDataListenerWrapper(env, jankDataListenerObject));
+static void nativeFlushJankData(JNIEnv* env, jclass clazz, jlong listener) {
+ sp<JankDataListenerWrapper> wrapper = reinterpret_cast<JankDataListenerWrapper*>(listener);
+ if (wrapper == nullptr) {
+ return;
+ }
+ wrapper->flushJankData();
+}
+
+static void nativeRemoveJankDataListener(JNIEnv* env, jclass clazz, jlong listener,
+ jlong afterVsync) {
+ sp<JankDataListenerWrapper> wrapper = reinterpret_cast<JankDataListenerWrapper*>(listener);
+ if (wrapper == nullptr) {
+ return;
+ }
+ wrapper->removeListener(afterVsync);
}
static jint nativeGetGPUContextPriority(JNIEnv* env, jclass clazz) {
@@ -2436,12 +2461,14 @@
(void*)nativeRemoveCurrentInputFocus},
{"nativeSetFrameTimelineVsync", "(JJ)V",
(void*)nativeSetFrameTimelineVsync },
- {"nativeAddJankDataListener", "(JJ)V",
- (void*)nativeAddJankDataListener },
- {"nativeRemoveJankDataListener", "(J)V",
+ {"nativeFlushJankData", "(J)V",
+ (void*)nativeFlushJankData },
+ {"nativeRemoveJankDataListener", "(JJ)V",
(void*)nativeRemoveJankDataListener },
- {"nativeCreateJankDataListenerWrapper", "(Landroid/view/SurfaceControl$OnJankDataListener;)J",
+ {"nativeCreateJankDataListenerWrapper", "(JLandroid/view/SurfaceControl$OnJankDataListener;)J",
(void*)nativeCreateJankDataListenerWrapper },
+ {"nativeGetJankDataListenerWrapperFinalizer", "()J",
+ (void*)nativeGetJankDataListenerWrapperFinalizer },
{"nativeGetGPUContextPriority", "()I",
(void*)nativeGetGPUContextPriority },
{"nativeSetTransformHint", "(JI)V",
diff --git a/core/proto/android/content/res/color_state_list.proto b/core/proto/android/content/res/color_state_list.proto
new file mode 100644
index 0000000..3d0d8a8
--- /dev/null
+++ b/core/proto/android/content/res/color_state_list.proto
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 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 optional 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.
+ */
+
+syntax = "proto2";
+
+option java_multiple_files = true;
+
+package android.content.res;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+/**
+ * An android.content.res.ColorStateList object.
+ */
+message ColorStateListProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+ repeated StateSpec state_specs = 1;
+ repeated int32 colors = 2 [packed = true];
+
+ message StateSpec {
+ repeated int32 state = 1 [packed = true];
+ }
+}
diff --git a/core/proto/android/widget/remoteviews.proto b/core/proto/android/widget/remoteviews.proto
index d24da03..f08ea1b 100644
--- a/core/proto/android/widget/remoteviews.proto
+++ b/core/proto/android/widget/remoteviews.proto
@@ -51,6 +51,26 @@
optional RemoteViewsProto landscape_remoteviews = 11;
optional bool is_root = 12;
optional bool has_draw_instructions = 13;
+ repeated bytes bitmap_cache = 14;
+ optional RemoteCollectionCache remote_collection_cache = 15;
+
+ message RemoteCollectionCache {
+ message Entry {
+ optional int64 id = 1;
+ optional string uri = 2;
+ optional RemoteCollectionItems items = 3;
+ }
+
+ repeated Entry entries = 1;
+ }
+
+ message RemoteCollectionItems {
+ repeated int64 ids = 1 [packed = true];
+ repeated RemoteViewsProto views = 2;
+ optional bool has_stable_ids = 3;
+ optional int32 view_type_count = 4;
+ optional bool attached = 5;
+ }
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6c6add9..f61b6bf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5593,6 +5593,15 @@
<permission android:name="android.permission.BIND_TV_INPUT"
android:protectionLevel="signature|privileged" />
+ <!-- This permission is required among systems services to always keep the
+ binding with TvInputManagerService.
+ <p>This should only be used by the OEM TvInputService.
+ <p>Protection level: signature|privileged|vendorPrivileged
+ @hide
+ -->
+ <permission android:name="android.permission.ALWAYS_BOUND_TV_INPUT"
+ android:protectionLevel="signature|privileged|vendorPrivileged" />
+
<!-- Must be required by a {@link android.media.tv.interactive.TvInteractiveAppService}
to ensure that only the system can bind to it.
<p>Protection level: signature|privileged
diff --git a/core/res/res/anim/overlay_task_fragment_change.xml b/core/res/res/anim/overlay_task_fragment_change.xml
new file mode 100644
index 0000000..eb02ba8
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_change.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:showBackdrop="false">
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_bottom.xml b/core/res/res/anim/overlay_task_fragment_close_to_bottom.xml
new file mode 100644
index 0000000..d9487cb
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_bottom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromYDelta="0"
+ android:toYDelta="100%"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_left.xml b/core/res/res/anim/overlay_task_fragment_close_to_left.xml
new file mode 100644
index 0000000..3cdb77a
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_left.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromXDelta="0"
+ android:toXDelta="-100%"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_right.xml b/core/res/res/anim/overlay_task_fragment_close_to_right.xml
new file mode 100644
index 0000000..3764561
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_right.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromXDelta="0"
+ android:toXDelta="100%"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_top.xml b/core/res/res/anim/overlay_task_fragment_close_to_top.xml
new file mode 100644
index 0000000..a8bfbbd
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_top.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromYDelta="0"
+ android:toYDelta="-100%"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_bottom.xml b/core/res/res/anim/overlay_task_fragment_open_from_bottom.xml
new file mode 100644
index 0000000..1d1223f
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_bottom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromYDelta="100%"
+ android:toYDelta="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_left.xml b/core/res/res/anim/overlay_task_fragment_open_from_left.xml
new file mode 100644
index 0000000..5e5e080
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_left.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromXDelta="-100%"
+ android:toXDelta="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_right.xml b/core/res/res/anim/overlay_task_fragment_open_from_right.xml
new file mode 100644
index 0000000..5674ff3
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_right.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromXDelta="100%"
+ android:toXDelta="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_top.xml b/core/res/res/anim/overlay_task_fragment_open_from_top.xml
new file mode 100644
index 0000000..2e3dd0a
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_top.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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.
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate
+ android:fromYDelta="-100%"
+ android:toYDelta="0"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index e44c727..565d584 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -62,7 +62,7 @@
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
- android:layout_toStartOf="@id/expand_button"
+ android:layout_toStartOf="@id/notification_buttons_column"
android:layout_alignWithParentIfMissing="true"
android:clipChildren="false"
android:gravity="center_vertical"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0c6d49e..336eb31 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Foutverslag"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Beëindig sessie"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Skermskoot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Foutverslag"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Dit sal inligting oor die huidige toestand van jou toestel insamel om as \'n e-posboodskap te stuur. Dit sal \'n tydjie neem vandat die foutverslag begin is totdat dit reg is om gestuur te word; wees asseblief geduldig."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiewe verslag"</string>
@@ -484,7 +486,7 @@
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Laat die program toe om jou Android TV-toestel se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
<string name="permlab_bodySensors" msgid="662918578601619569">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program gebruik word"</string>
- <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die program gebruik word."</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die app toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die app gebruik word."</string>
<string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program op agtergrond is"</string>
<string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lees kalendergebeurtenisse en -besonderhede"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Kies om draadlose ontfouting te deaktiveer."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Toetsraamwerkmodus is geaktiveer"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Voer \'n fabriekterugstelling uit om Toetsraamwerkmodus te deaktiveer."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Reekskonsole is geaktiveer"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Werkverrigting word beïnvloed. Gaan selflaaiprogram na om te deaktiveer."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentele MTE is geaktiveer"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Los die volumesleutels. Druk en hou albei volumesleutels weer 3 sekondes lank in om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aan te skakel."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Kies \'n kenmerk om te gebruik wanneer jy op die toeganklikheidknoppie tik:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Kies \'n kenmerk om te gebruik saam met die toeganklikheidgebaar (swiep met twee vingers op van die onderkant van die skerm af):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Kies \'n kenmerk om te gebruik saam met die toeganklikheidgebaar (swiep met drie vingers op van die onderkant van die skerm af):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Raak en hou die toeganklikheidknoppie om tussen kenmerke te wissel."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Swiep op met twee vingers en hou om tussen kenmerke te wissel."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Swiep op met drie vingers en hou om tussen kenmerke te wissel."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string>
<string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Oproep aan die gang"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Keur tans \'n inkomende oproep"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Ongekategoriseer"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosies"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosiaal"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nuus"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Aanbevelings"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Jy stel die belangrikheid van hierdie kennisgewings."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Dit is belangrik as gevolg van die mense wat betrokke is."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Gepasmaakte appkennisgewing"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Toeganklikheidkortpadkieser op skerm"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Toeganklikheidkortpad"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Maak kennisgewingskerm toe"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Kieslys"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media speel/onderbreek"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-paneel op"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-paneel af"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-paneel links"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe dit werk"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Stel Vingerafdrukslot weer op"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> het nie goed gewerk nie en is uitgevee"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> het nie goed gewerk nie en is uitgevee"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met vingerafdruk te ontsluit."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met jou vingerafdruk te ontsluit."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Stel Gesigslot weer op"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jou gesigmodel het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met gesig te ontsluit."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Stel op"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nie nou nie"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm vir <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Wissel gebruiker"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Demp"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tik om klank te demp"</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 39152fe..ad8874f 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"የሳንካ ሪፖርት"</string>
<string name="global_action_logout" msgid="6093581310002476511">"ክፍለ-ጊዜን አብቃ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ቅጽበታዊ ገፅ ዕይታ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"የሳንካ ሪፖርት"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ይሄ እንደ የኢሜይል መልዕክት አድርጎ የሚልከውን ስለመሣሪያዎ የአሁኑ ሁኔታ መረጃ ይሰበስባል። የሳንካ ሪፖርቱን ከመጀመር ጀምሮ እስኪላክ ድረስ ትንሽ ጊዜ ይወስዳል፤ እባክዎ ይታገሱ።"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"መስተጋብራዊ ሪፖርት"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ገመድ-አልባ debuggingን ለማሰናከል ይምረጡ።"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"የሙከራ ጥቅል ሁነታ ነቅቷል"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"የመሞከሪያ ጥቅል ሁነታን ለማሰናከል የፋብሪካ ዳግም ቅንብርን ይሞክሩ።"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"ተከታታይ ኮንሶል ነቅቷል"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"አፈጻጸም ተጽዕኖ አርፎበታል። ለማሰናከል፣ bootloader ን ይፈትሹ።"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"የሙከራ MTE ነቅቷል።"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"የድምጽ መጠን ቁልፎቹን ይልቀቁ። <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለማብራት ሁለቱንም የድምጽ መጠን ቁልፎች በድጋሚ ለ3 ሰከንዶች ተጭነው ይያዙ።"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን ባሕሪ ይምረጡ፦"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ከተደራሽነት ጣት ምልክት ጋር የሚጠቀሙበት ባሕሪ ይምረጡ (በሁለት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ከተደራሽነት ጣት ምልክት ጋር አብረው የሚጠቀሙበት ባሕሪ ይምረጡ (በሦስት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"በባሕሪያት መካከል ለመቀያየር የተደራሽነት አዝራሩን ነክተው ይያዙ።"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"በባሕሪያት መካከል ለመቀያየር በሁለት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"በባሕሪያት መካከል ለመቀያየር በሶስት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ማጉላት"</string>
<string name="user_switched" msgid="7249833311585228097">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
<string name="user_switching_message" msgid="1912993630661332336">"ወደ <xliff:g id="NAME">%1$s</xliff:g> በመቀየር ላይ…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"እየተካሄደ ያለ ጥሪ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ገቢ ጥሪ ማጣራት"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ያልተመደቡ"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ማስተዋወቂያዎች"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"ማህበራዊ"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ዜና"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"ምክሮች"</string>
<string name="importance_from_user" msgid="2782756722448800447">"የእነዚህን ማሳወቂያዎች አስፈላጊነት አዘጋጅተዋል።"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ይሄ በሚሳተፉ ሰዎች ምክንያት አስፈላጊ ነው።"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ብጁ የመተግበሪያ ማሳወቂያ"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"የማያ ገፅ ላይ ተደራሽነት አቋራጭ መራጭ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"የተደራሽነት አቋራጭ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"የማሳወቂያ ጥላን አሰናብት"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ምናሌ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ሚዲያ አጫውት/ለአፍታ አቁም"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ከDpad በላይ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ከDpad በታች"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ከDpad በስተግራ"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"እንዴት እንደሚሠራ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"በመጠባበቅ ላይ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> በደንብ እየሠራ አልነበረም እና ተሰርዟል"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> በደንብ እየሠሩ አልነበረም እና ተሰርዘዋል"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> በደንብ እየሠራ አልነበረም እና ተሰርዟል። ስልክዎን በጣት አሻራ ለመክፈት እንደገና ያዋቅሩት።"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> በደንብ እየሠሩ አልነበረም እና ተሰርዘዋል። ስልክዎን በጣት አሻራ ለመክፈት እንደገና ያዋቅሯቸው።"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"በመልክ መክፈትን እንደገና ያዋቅሩ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"የእርስዎ የመልክ ሞዴል በደንብ እየሠራ አልነበረም እና ተሰርዟል። ስልክዎን በመልክ ለመክፈት እንደገና ያዋቅሩት።"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ያዋቅሩ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"አሁን አይደለም"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ለ<xliff:g id="USER_NAME">%s</xliff:g> ማንቂያ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ተጠቃሚ ቀይር"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ድምፀ-ከል አድርግ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ድምፀ-ከል አድርግ ለማድረግ መታ ያድርጉ"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3d066d9..ee90210 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -269,6 +269,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"تقرير الأخطاء"</string>
<string name="global_action_logout" msgid="6093581310002476511">"إنهاء الجلسة"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"لقطة شاشة"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"تقرير الأخطاء"</string>
<string name="bugreport_message" msgid="5212529146119624326">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، يُرجى الانتظار."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"تقرير تفاعلي"</string>
@@ -1415,6 +1417,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"انقر لإيقاف ميزة \"تصحيح الأخطاء اللاسلكي\""</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"تم تفعيل وضع \"مفعّل الاختبار\""</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"وحدة التحكّم التسلسلية مفعّلة"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"الأداء متأثر. لإيقاف وحدة التحكّم، تحقّق من برنامج الإقلاع."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"الميزة التجريبية إضافة وضع علامات الذاكرة (MTE) مفعّلة"</string>
@@ -1759,12 +1765,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم تفعيل <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم إيقاف <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ارفع إصبعَيك عن مفتاحَي مستوى الصوت. لتفعيل خدمة \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"، اضغط مع الاستمرار على كلا مفتاحَي مستوى الصوت مجددًا لمدة 3 ثوانٍ."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"يمكنك اختيار إحدى الميزات لاستخدامها عند النقر على زر أدوات تمكين الوصول:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"يمكنك اختيار إحدى الميزات لاستخدامها مع إيماءة أدوات تمكين الوصول (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام إصبعين):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"يمكنك اختيار إحدى الميزات التالية لاستخدامها مع إيماءة أدوات تمكين الوصول (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام ثلاثة أصابع):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"للتبديل بين الخدمات، يمكنك النقر مع الاستمرار على زر أدوات تمكين الوصول."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"للتبديل بين الخدمات، مرّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام إصبعين مع تثبيتهما."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"للتبديل بين الميزات، مرّر سريعًا من أسفل الشاشة لأعلاها بثلاثة أصابع مع تثبيتها."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"سيتم فتح الميزة عند النقر على زر أدوات تسهيل الاستخدام في المرة القادمة"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام إصبعَين وارفعما بعدها بسرعة."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام 3 أصابع وارفع أصابعك بعدها بسرعة."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"التكبير"</string>
<string name="user_switched" msgid="7249833311585228097">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"جارٍ التبديل إلى <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1980,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"مكالمة جارية"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"يتم فحص المكالمة الواردة"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"غير مصنفة"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"العروض الترويجية"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"التواصل الاجتماعي"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"الأخبار"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"الاقتراحات"</string>
<string name="importance_from_user" msgid="2782756722448800447">"لقد عيَّنت أهمية هذه الإشعارات."</string>
<string name="importance_from_person" msgid="4235804979664465383">"هذه الرسالة مهمة نظرًا لأهمية الأشخاص المعنيين."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"إشعار تطبيق مخصّص"</string>
@@ -2196,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"أداة اختيار اختصارات أدوات تمكين الوصول على الشاشة"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"اختصارات أدوات تمكين الوصول"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"إغلاق مركز الإشعارات"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"القائمة"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"تشغيل الوسائط أو إيقافها مؤقتًا"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"زرّ الاتجاه للأعلى"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"زرّ الاتجاه للأسفل"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"زرّ الاتجاه لليسار"</string>
@@ -2422,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"طريقة العمل"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"بانتظار الإزالة من الأرشيف…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"إعادة إعداد ميزة \"فتح الجهاز ببصمة الإصبع\""</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"هناك مشكلة في <xliff:g id="FINGERPRINT">%s</xliff:g> وتم حذفها"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"هناك مشكلة في <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> وتم حذفهما"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"هناك مشكلة في <xliff:g id="FINGERPRINT">%s</xliff:g> وتم حذفها. يُرجى إعدادها مرة أخرى لفتح قفل هاتفك باستخدام بصمة الإصبع."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"هناك مشكلة في <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> وتم حذفهما. يُرجى إعادة إعدادهما لفتح قفل هاتفك باستخدام بصمة الإصبع."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"إعادة إعداد ميزة \"فتح الجهاز بالتعرّف على الوجه\""</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"هناك مشكلة في نموذج الوجه الخاص بك وتم حذفه. يُرجى إعداده مرة أخرى لفتح قفل هاتفك باستخدام وجهك."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"إعداد"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"لاحقًا"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"تنبيه لـ \"<xliff:g id="USER_NAME">%s</xliff:g>\""</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تبديل المستخدم"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"كتم الصوت"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"انقر لكتم الصوت"</string>
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index b9c072b..599d469 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"বাগ সম্পর্কীয় অভিযোগ"</string>
<string name="global_action_logout" msgid="6093581310002476511">"ছেশ্বন সমাপ্ত কৰক"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"স্ক্ৰীনশ্বট"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"বাগ সম্পর্কীয় অভিযোগ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"এই কার্যই ইমেইল বাৰ্তা হিচাপে পঠিয়াবলৈ আপোনাৰ ডিভাইচৰ বৰ্তমান অৱস্থাৰ বিষয়ে তথ্য সংগ্ৰহ কৰিব৷ ইয়াক বাগ সম্পর্কীয় অভিযোগ পঠিওৱা কাৰ্য আৰম্ভ কৰোঁতে অলপ সময় লাগিব; অনুগ্ৰহ কৰি ধৈৰ্য ধৰক।"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ইণ্টাৰেক্টিভ অভিযোগ"</string>
@@ -606,12 +608,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"এপ্টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰি উলিয়াবলৈ আৰু সেইসমূহৰ সৈতে পেয়াৰ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰক"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"এপ্টোক পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰিবলৈ অনুমতি দিয়ে"</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰ কৰা"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"এপ্টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰ কৰিবলৈ দিয়ে"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰাভিযান কৰা"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"এপ্টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰাভিযান কৰিবলৈ দিয়ে"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰক"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"এপ্টোক নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচসমূহৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ক"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"নিকটৱৰ্তী ৱাই-ফাই ডিভাইচসমূহৰ সৈতে ভাব বিনিময় কৰক"</string>
- <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এপ্টোক বিজ্ঞাপন প্ৰচাৰ কৰিবলৈ, সংযোগ কৰিবলৈ আৰু নিকটৱৰ্তী ৱাই-ফাই ডিভাইচৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এপ্টোক বিজ্ঞাপন প্ৰচাৰাভিযান কৰিবলৈ, সংযোগ কৰিবলৈ আৰু নিকটৱৰ্তী ৱাই-ফাই ডিভাইচৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"অগ্ৰাধিকাৰ দিয়া NFC পৰিশোধ সেৱাৰ তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"এপ্টোক অগ্ৰাধিকাৰ দিয়া nfc পৰিশোধ সেৱাৰ পঞ্জীকৃত সহায়কসমূহ আৰু পৰিশোধ কৰিব লগা লক্ষ্যস্থান দৰে তথ্য পাবলৈ অনুমতি দিয়ে।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ৱায়াৰলেচ ডি\'বাগিং অক্ষম কৰিবলৈ বাছনি কৰক।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"টেষ্ট হাৰনেছ ম’ড সক্ষম কৰা আছে"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"টেষ্ট হাৰনেছ ম’ড অক্ষম কৰিবলৈ ফেক্টৰী ৰিছেট কৰক।"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"ক্ৰমিক কনছ’ল সক্ষম কৰা আছে"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"কাৰ্যক্ষমতা প্ৰভাৱিত হৈছে। অক্ষম কৰিবলৈ বুটল’ডাৰ পৰীক্ষা কৰক।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"পৰীক্ষামূলক MTE সক্ষম কৰা হ\'ল"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম কী এৰি দিয়ক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰিবলৈ, দুয়োটা ভলিউম কী পুনৰ ৩ ছেকেণ্ডৰ বাবে টিপি হেঁচি ৰাখক।"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"আপুনি সাধ্য-সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"সাধ্য-সুবিধাৰ নির্দেশৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক (দুটা আঙুলিৰে স্ক্রীনখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"সাধ্য-সুবিধাৰ নির্দেশৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক (তিনিটা আঙুলিৰে স্ক্রীনখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"সুবিধাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ সাধ্য-সুবিধাৰ বুটামটো স্পৰ্শ কৰি ধৰি ৰাখক।"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"সুবিধাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ দুটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"সুবিধাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ তিনিটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"আপুনি ইয়াৰ পাছত সাধ্য-সুবিধা বুটামটোত টিপিলে সুবিধাটো খোল খাব"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ২ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ৩ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বিবৰ্ধন"</string>
<string name="user_switched" msgid="7249833311585228097">"বৰ্তমানৰ ব্যৱহাৰকাৰী <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>লৈ সলনি কৰি থকা হৈছে…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"চলি থকা কল"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"এটা অন্তৰ্গামী কলৰ পৰীক্ষা কৰি থকা হৈছে"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"শ্ৰেণীবদ্ধ নকৰা"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"প্ৰমোশ্বন"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"সামাজিক"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"বাতৰি"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"চুপাৰিছ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"এই জাননীবোৰৰ গুৰুত্ব আপুনি ছেট কৰব লাগিব।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"এই কার্যৰ সৈতে জড়িত থকা লোকসকলক ভিত্তি কৰি এইয়া গুৰুত্বপূর্ণ বুলি বিবেচনা কৰা হৈছ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"কাষ্টম এপৰ জাননী"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"স্ক্ৰীনত সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট বাছনি কৰাৰ সুবিধা"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"সাধ্য সুবিধাৰ শ্বৰ্টকাট"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"জাননী পেনেল অগ্ৰাহ্য কৰক"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"মেনু"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"মিডিয়া প্লে’/পজ কৰক"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ডিপেডৰ ওপৰফালৰ বুটাম"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ডিপেডৰ তলফালৰ বুটাম"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ডিপেডৰ বাওঁফালৰ বুটাম"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ই কেনেকৈ কাম কৰে"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"বিবেচনাধীন হৈ আছে..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেয়া মচি পেলোৱা হৈছে"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে। ফিংগাৰপ্ৰিণ্টৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ এইটো পুনৰ ছেট আপ কৰক।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেয়া মচি পেলোৱা হৈছে। ফিংগাৰপ্ৰিণ্টৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ সেয়া পুনৰ ছেট আপ কৰক।"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ফে’চ আনলক পুনৰ ছেট আপ কৰক"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপোনাৰ মুখাৱয়বৰ মডেলটোৱে ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে। মুখাৱয়বৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ এইটো পুনৰ ছেট আপ কৰক।"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ছেট আপ কৰক"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এতিয়া নহয়"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>ৰ বাবে এলাৰ্ম"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"মিউট কৰক"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ধ্বনি মিউট কৰিবলৈ টিপক"</string>
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 32210f7..a22cf4a 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Baq hesabatı"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Sessiyanı sonlandırın"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Skrinşot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Baq hesabatı"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Bu, sizin hazırkı cihaz durumu haqqında məlumat toplayacaq ki, elektron məktub şəklində göndərsin. Baq raportuna başlamaq üçün bir az vaxt lazım ola bilər, bir az səbr edin."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"İnteraktiv hesabat"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"WiFi sazlamasını deaktiv etmək üçün seçin."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Rejimi aktivdir"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Test Rejimini deaktiv etmək üçün fabrika ayarlarına sıfırlayın."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Ardıcıl konsol aktiv edildi"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performans təsirlənir. Söndürməkçün yükləyicini yoxlayın."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimental MTE aktiv edilib"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Səs düymələrini buraxın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etmək üçün hər iki səs düyməsinə yenidən 3 saniyə basıb saxlayın."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Xüsusi imkanlar düyməsinə toxunanda istədiyiniz funksiyanı seçin:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Əlçatımlılıq jesti (iki barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Əlçatımlılıq jesti (üç barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funksiyalar arasında keçid etmək üçün xüsusi imkanlar düyməsini basıb saxlayın."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funksiyalar arasında keçid etmək üçün iki barmağınızla yuxarı sürüşdürüb saxlayın."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funksiyalar arasında keçid etmək üçün üç barmağınızla yuxarı doğru sürüşdürüb saxlayın."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Böyütmə"</string>
<string name="user_switched" msgid="7249833311585228097">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Davam edən zəng"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Gələn zəng göstərilir"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Kateqoriyasız"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Tanıtımlar"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosial"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Xəbərlər"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tövsiyələr"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Bildirişlərin əhəmiyyətini Siz ayarlaryırsınız."</string>
<string name="importance_from_person" msgid="4235804979664465383">"İnsanlar cəlb olunduğu üçün bu vacibdir."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Fərdi tətbiq bildirişi"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda Əlçatımlılıq Qısayolu Seçicisi"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Əlçatımlılıq Qısayolu"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Bildiriş Göstərişini qapadın"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Medianı oxudun/durdurun"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Yuxarı"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Aşağı"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Sola"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Şəxsi sahə"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Həssas bildiriş kontenti gizlədildi"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Güvənlik üçün tətbiq kontenti ekran paylaşımından gizlədildi"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Tətbiq kontenti güvənlik məsələlərinə görə ekran paylaşımından gizlədildi"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Peykə avtomatik qoşulub"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesaj göndərə və qəbul edə bilərsiniz"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Haqqında"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gözləmədə..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmaqla Kilidaçmanı yenidən ayarlayın"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxşı işləmirdi və silindi"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxşı işləmirdi və silindi"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxşı işləmirdi və silindi. Telefonu barmaq izi ilə kiliddən çıxarmaq üçün onu yenidən ayarlayın."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxşı işləmirdi və silindi. Telefonu barmaq izi ilə kiliddən çıxarmaq üçün onları yenidən ayarlayın."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Üzlə Kilidaçmanı yenidən ayarlayın"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Üz modeliniz yaxşı işləmirdi və silindi. Telefonu üzlə kiliddən çıxarmaq üçün onu yenidən ayarlayın."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarlayın"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"İndi yox"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> üçün alarm"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"İstifadəçini dəyişin"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Susdurun"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Susdurmaq üçün toxunun"</string>
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ac01883..8da8c2f 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Javi grešku"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snimak ekrana"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Javi grešku"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ovim će se prikupiti informacije o trenutnom stanju uređaja kako bi bile poslate u poruci e-pošte. Od započinjanja izveštaja o grešci do trenutka za njegovo slanje proći će neko vreme; budite strpljivi."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv. izveštaj"</string>
@@ -517,11 +519,11 @@
<string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičkih aktivnosti"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ova aplikacija može da prepozna fizičke aktivnosti."</string>
<string name="permlab_camera" msgid="6320282492904119413">"snimanje fotografija i videa"</string>
- <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video snimke pomoću kamere dok se aplikacija koristi."</string>
- <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video snimke u pozadini"</string>
+ <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video pomoću kamere dok se aplikacija koristi."</string>
+ <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video u pozadini"</string>
<string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku."</string>
<string name="permlab_systemCamera" msgid="3642917457796210580">"Dozvolite nekoj aplikaciji ili usluzi da pristupa kamerama sistema da bi snimala slike i video snimke"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video snimke pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom."</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ova aplikacija može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću neke aplikacije)."</string>
<string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Dozvolite aplikaciji ili usluzi da pristupa kameri kao korisnik sistema bez grafičkog korisničkog interfejsa."</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izaberite da biste onemogućili bežično otklanjanje grešaka."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je režim probnog korišćenja"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogućena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da biste onemogući konzolu, proverite pokretački program."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tastere za jačinu zvuka. Da biste uključili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite oba tastera za jačinu zvuka 3 sekunde."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću tri prsta prevucite nagore od dna ekrana):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Da biste prelazili sa jedne funkcije na drugu, dodirnite i zadržite dugme Pristupačnost."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću dva prsta i zadržite."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću tri prsta i zadržite."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećanje"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv je u toku"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Proverava se dolazni poziv"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizovano"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Društvene mreže"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Vesti"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Preporuke"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vi podešavate važnost ovih obaveštenja."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ovo je važno zbog ljudi koji učestvuju."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođeno obaveštenje o aplikaciji"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alatka za biranje prečica za pristupačnost na ekranu"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbaci traku sa obaveštenjima"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Pusti/pauziraj medije"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"nagore na D-pad-u"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"nadole na D-pad-u"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"nalevo na D-pad-u"</string>
@@ -2419,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Princip rada"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo podesite otključavanje otiskom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nije funkcionisao i izbrisali smo ga"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu funkcionisali i izbrisali smo ih"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nije funkcionisao i izbrisali smo ga. Ponovo ga podesite da biste telefon otključavali otiskom prsta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu funkcionisali i izbrisali smo ih. Ponovo ih podesite da biste telefon otključavali otiskom prsta."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo podesite otključavanje licem"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Vaš model lica nije funkcionisao i izbrisali smo ga. Ponovo ga podesite da biste telefon otključavali licem."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Podesi"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Promeni korisnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite da biste isključili zvuk"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index cbcc90a..28f9ebc 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Справаздача пра памылкі"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Скончыць сеанс"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Здымак экрана"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Справаздача"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Будзе збiрацца iнфармацыя пра бягучы стан прылады, якая будзе адпраўляцца на электронную пошту. Стварэнне справаздачы пра памылкi зойме некаторы час."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Інтэрактыўная справаздача"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Выберыце, каб выключыць адладку па Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Тэставы рэжым уключаны"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Паслядоўная кансоль уключана"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Паказчык прадукцыйнасці змяніўся. Каб выключыць кансоль, праверце загрузчык."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Эксперыментальнае пашырэнне тэгаў памяці (MTE) уключана"</string>
@@ -1757,12 +1763,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Адпусціце клавішы гучнасці. Каб уключыць сэрвіс \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце абедзве клавішы гучнасці яшчэ раз і ўтрымлівайце іх на працягу 3 секунд."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Выберыце функцыю, якую будзеце выкарыстоўваць пры націску кнопкі спецыяльных магчымасцей:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Выберыце функцыю, якую будзеце выкарыстоўваць з жэстам спецыяльных магчымасцей (правесці двума пальцамі па экране знізу ўверх):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Выберыце функцыю, якую будзеце выкарыстоўваць з жэстам спецыяльных магчымасцей (правесці трыма пальцамі па экране знізу ўверх):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Каб пераключыцца на іншыя функцыі, націсніце і ўтрымлівайце кнопку спецыяльных магчымасцей."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Каб пераключыцца на іншую функцыю, правядзіце ўверх двума пальцамі і ўтрымлівайце іх на экране."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Каб пераключыцца на іншую функцыю, правядзіце ўверх трыма пальцамі і ўтрымлівайце іх на экране."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функцыя адкрыецца, калі вы наступным разам націснеце на кнопку спецыяльных магчымасцей"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце двума пальцамі ад нізу экрана ўверх і хутка адпусціце."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце трыма пальцамі ад нізу экрана ўверх і хутка адпусціце."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Павелічэнне"</string>
<string name="user_switched" msgid="7249833311585228097">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Пераход у рэжым \"<xliff:g id="NAME">%1$s</xliff:g>\"..."</string>
@@ -1978,6 +1987,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Бягучы выклік"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Фільтраванне ўваходнага выкліку"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Некатэгарызаванае"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Прома-акцыі"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Сацыяльныя сеткі"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Навіны"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рэкамендацыі"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Вы задалі важнасць гэтых апавяшчэнняў."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Апавяшчэнне пра карыстальніцкую праграму"</string>
@@ -2194,6 +2207,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Налада хуткага доступу да спецыяльных магчымасцей на экране"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хуткі доступ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрыць шчыток апавяшчэнняў"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Прайграць або прыпыніць медыяфайл"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Уверх на панэлі кіравання"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Уніз на панэлі кіравання"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Улева на панэлі кіравання"</string>
@@ -2420,12 +2435,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як гэта працуе"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"У чаканні..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Наладзіць разблакіроўку адбіткам пальца паўторна"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" не працаваў належным чынам і быў выдалены"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" не працавалі належным чынам і былі выдалены"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" не працаваў належным чынам і быў выдалены. Каб мець магчымасць разблакіраваць тэлефон з дапамогай адбітка пальца, наладзьце яго яшчэ раз."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" не працавалі належным чынам і былі выдалены. Каб мець магчымасць разблакіраваць тэлефон з дапамогай адбітка пальца, наладзьце іх яшчэ раз."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Паўторна наладзьце распазнаванне твару"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Мадэль твару не працавала належным чынам і была выдалена. Каб мець магчымасць разблакіраваць тэлефон з дапамогай распазнавання твару, наладзьце яго яшчэ раз."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Наладзіць"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будзільнік карыстальніка <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Змяніць карыстальніка"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Выключыць гук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Націсніце, каб выключыць гук"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index affa311..b993477 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Сигнал за грешка"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Прекратяване на сесията"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Екранна снимка"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Сигнал за грешка"</string>
<string name="bugreport_message" msgid="5212529146119624326">"По този начин ще се събере информация за текущото състояние на устройството ви, която да се изпрати като имейл съобщение. След стартирането на процеса ще мине известно време, докато сигналът за програмна грешка бъде готов за подаване. Моля, имайте търпение."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактивен сигнал"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изберете, за да деактивирате безжичното отстраняване на грешки."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Режимът за тестова среда е активиран"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Серийната конзола е активирана"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ефективността е засегната. За да деактивирате, проверете програмата за първоначално зареждане."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Експерименталното разширение MTE е активирано"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е включена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е изключена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Освободете бутоните за силата на звука. За да включите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, отново натиснете двата бутона за силата на звука и задръжте за 3 секунди."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изберете функция, която да използвате, когато докоснете бутона за достъпност:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете коя функция да се използва с жеста за достъпност (прекарване на два пръста нагоре от долната част на екрана):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете коя функция да се използва с жеста за достъпност (прекарване на три пръста нагоре от долната част на екрана):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"За превключване между функциите докоснете и задръжте бутона за достъпност."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За превключване между функциите прекарайте два пръста нагоре и задръжте."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За превключване между функциите прекарайте три пръста нагоре и задръжте."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
<string name="user_switched" msgid="7249833311585228097">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Превключва се към: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущо обаждане"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Преглежда се входящо обаждане"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризирани"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоции"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Социални мрежи"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Новини"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Препоръки"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Зададохте важността на тези известия."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Това е важно заради участващите хора."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Персонализирано известие за приложение"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Инструмент за избор на пряк път към достъпността на екрана"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пряк път за достъпност"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Отхвърляне на падащия панел с известия"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Пускане/пауза на мултимедията"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Контролен пад – горе"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Контролен пад – долу"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Контролен пад – ляво"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Начин на работа"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Изчаква..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Повторно настройване на „Отключване с отпечатък“"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Отпечатъкът „<xliff:g id="FINGERPRINT">%s</xliff:g>“ бе изтрит, защото не работеше добре"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Отпечатъците „<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>“ и „<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>“ бяха изтрити, защото не работеха добре"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Отпечатъкът „<xliff:g id="FINGERPRINT">%s</xliff:g>“ бе изтрит, защото не работеше добре. Настройте го отново, за да отключвате телефона си с отпечатък."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Отпечатъците „<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>“ и „<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>“ бяха изтрити, защото не работеха добре. Настройте ги отново, за да отключвате телефона си с отпечатък."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Повторно настройване на „Отключване с лице“"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Моделът на лицето ви бе изтрит, защото не работеше добре. Настройте го отново, за да отключвате телефона си с лице."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настройване"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будилник за <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Смяна на потребителя"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Спиране на звука"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Докоснете, за да спрете звука"</string>
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 889de67..ca5c471 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"ত্রুটির প্রতিবেদন"</string>
<string name="global_action_logout" msgid="6093581310002476511">"সেশন শেষ করুন"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"স্ক্রিনশট নিন"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"সমস্যার রিপোর্ট"</string>
<string name="bugreport_message" msgid="5212529146119624326">"এটি একটি ই-মেল মেসেজ পাঠানোর জন্য আপনার ডিভাইসের বর্তমান অবস্থা সম্পর্কে তথ্য সংগ্রহ করবে৷ ত্রুটির প্রতিবেদন শুরুর সময় থেকে এটি পাঠানোর জন্য প্রস্তুত হতে কিছুটা সময় নেবে; অনুগ্রহ করে ধৈর্য রাখুন৷"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ইন্টারেক্টিভ প্রতিবেদন"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ওয়্যারলেস ডিবাগিং বন্ধ করতে বেছে নিন।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"টেস্ট হারনেস মোড চালু আছে"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"টেস্ট হারনেস মোড বন্ধ করতে ফ্যাক্টরি রিসেট করুন।"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"সিরিয়াল কনসোল চালু করা হয়েছে"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"পারফর্ম্যান্সে এর প্রভাব পড়বে। চালানো বন্ধ করতে \'বুটলোডার\' প্রোগ্রামে এটিকে চেক করে দেখুন।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"পরীক্ষামূলক MTE চালু আছে"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম \'কী\' রিলিজ করুন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করুন, দু\'টি ভলিউম \'কী\' আবার প্রেস করে ৩ সেকেন্ড ধরে রাখুন।"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"অ্যাক্সেসিবিলিটি বোতামে ট্যাপ করে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"অ্যাক্সেসিবিলিটি জেসচারের (দুটি আঙ্গুল দিয়ে স্ক্রিনের নিচে থেকে উপরের দিকে সোয়াইপ করুন) সাহায্যে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"অ্যাক্সেসিবিলিটি জেসচারের (তিনটি আঙ্গুল দিয়ে স্ক্রিনের নিচে থেকে উপরের দিকে সোয়াইপ করুন) সাহায্যে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"একটি ফিচার থেকে অন্যটিতে যেতে অ্যাক্সেসিবিলিটি বোতাম টাচ করে ধরে থাকুন।"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"একটি ফিচার থেকে অন্যটিতে যেতে, দুটি আঙ্গুল দিয়ে নিচে থেকে উপরের দিকে সোয়াইপ করে ধরে থাকুন।"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"একটি ফিচার থেকে অন্যটিতে যেতে, তিনটি আঙ্গুল দিয়ে উপরের দিকে সোয়াইপ করে ধরে থাকুন।"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বড় করে দেখা"</string>
<string name="user_switched" msgid="7249833311585228097">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> প্রোফাইলে পাল্টানো হচ্ছে…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"চালু থাকা কল"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ইনকামিং কল স্ক্রিনিং করা হচ্ছে"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"বিভাগ নির্ধারিত নয়"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"প্রোমোশন"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"সোশ্যাল"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"খবর"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"সাজেশন"</string>
<string name="importance_from_user" msgid="2782756722448800447">"আপনি এই বিজ্ঞপ্তিগুলির গুরুত্ব সেট করেছেন।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"লোকজন জড়িত থাকার কারণে এটি গুরুত্বপূর্ণ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"কাস্টম অ্যাপ বিজ্ঞপ্তি"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"অন-স্ক্রিন অ্যাক্সেসিবিলিটি শর্টকাট বেছে নেওয়ার বিকল্প"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"অ্যাক্সেসিবিলিটি শর্টকাট"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"বিজ্ঞপ্তি শেড বাতিল করুন"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"মেনু"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"মিডিয়া প্লে/পজ করুন"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ডিপ্যাড (Dpad)-এর উপরে"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ডিপ্যাড (Dpad)-এর নিচে"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ডিপ্যাড (Dpad)-এর বাঁদিকে"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"এটি কীভাবে কাজ করে"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"বাকি আছে…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করুন"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ভালোভাবে কাজ করছিল না এবং সেটি মুছে ফেলা হয়েছে"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ভালোভাবে কাজ করছিল না এবং মুছে ফেলা হয়েছে"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ভালোভাবে কাজ করছিল না বলে সেটি মুছে ফেলা হয়েছে। ফিঙ্গারপ্রিন্ট ব্যবহার করে আপনার ফোন আনলক করতে হলে এটি আবার সেট-আপ করুন।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ভালোভাবে কাজ করছিল না বলে মুছে ফেলা হয়েছে। ফিঙ্গারপ্রিন্ট ব্যবহার করে আপনার ফোন আনলক করতে হলে সেগুলি আবার সেট-আপ করুন।"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"\'ফেস আনলক\' আবার সেট-আপ করুন"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপনার ফেস মডেল ভালোভাবে কাজ করছিল না বলে সেটি মুছে ফেলা হয়েছে। ফেস ব্যবহার করে আপনার ফোন আনলক করতে হলে এটি আবার সেট-আপ করুন।"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"সেট-আপ করুন"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এখন নয়"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-এর জন্য অ্যালার্ম"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ব্যবহারকারী পাল্টান"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"মিউট করুন"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"সাউন্ড মিউট করতে ট্যাপ করুন"</string>
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index af9ac56..4a1aaed 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Izvještaj o greškama"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snimak ekrana"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Izvještaj o greškama"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ovim će se prikupljati informacije o trenutnom stanju uređaja, koji će biti poslani kao e-poruka. Može malo potrajati dok se izvještaj o greškama ne kreira i bude spreman za slanje. Budite strpljivi."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktivni izvještaj"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Odaberite da onemogućite bežično otklanjanje grešaka."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen način rada okvira za testiranje"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Izvršite vraćanje na fabričke postavke da onemogućite način rada okvira za testiranje."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola omogućena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da onemogućite, provjerite program za učitavanje operativnog sistema."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za jačinu zvuka. Da uključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za jačinu zvuka 3 sekunde."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Odaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koju ćete koristiti kada izvedete pokret za pristupačnost (s dva prsta prevucite prema gore s dna ekrana):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koju ćete koristiti kada izvedete pokret za pristupačnost (s tri prsta prevucite prema gore s dna ekrana):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Za prebacivanje između funkcija, dodirnite i zadržite dugme Pristupačnost."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da prebacujete između funkcija, s dva prsta prevucite prema gore i zadržite."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da prebacujete između funkcija, s tri prsta prevucite prema gore i zadržite."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećavanje"</string>
<string name="user_switched" msgid="7249833311585228097">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u toku"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nije kategorizirano"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Društveni mediji"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Vijesti"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Preporuke"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vi određujete značaj ovih obavještenja."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ovo je značajno zbog osoba koje su uključene."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođeno obavještenje aplikacije"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Okvir za odabir prečice za pristupačnost na ekranu"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbacite lokaciju za obavještenja"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reprodukcija/pauziranje medijskog sadržaja"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Upravljač gore"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Upravljač dolje"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Upravljač lijevo"</string>
@@ -2419,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako ovo funkcionira"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo postavite otključavanje otiskom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao, pa je izbrisan"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali, pa su izbrisani"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao, pa je izbrisan. Postavite ga ponovo da otključavate telefon otiskom prsta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali, pa su izbrisani. Postavite ih ponovo da otključavate telefon otiskom prsta."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo postavite otključavanje licem"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model lica nije dobro funkcionirao, pa je izbrisan. Postavite ga ponovo da otključavate telefon licem."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavite"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Prebaci na drugog korisnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite da isključite zvuk"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 66c81e6..a3b13f1 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -157,7 +157,7 @@
<string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Seguretat de xarxes mòbils"</string>
<string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Encriptació, notificacions de xarxes sense encriptació"</string>
<string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"S\'ha accedit a l\'identificador de dispositiu"</string>
- <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"A les <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una xarxa propera ha registrat l\'identificador únic del teu dispositiu (IMSI or IMEI) mentre s\'utilitzava la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
+ <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"A les <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una xarxa propera ha registrat l\'ID únic del dispositiu (IMSI or IMEI) amb la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
<string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"A les <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una xarxa propera ha registrat l\'identificador únic del teu dispositiu (IMSI or IMEI) mentre s\'utilitzava la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nAixò vol dir que s\'han registrat la teva ubicació, activitat o identitat. Tot i ser una pràctica habitual, pot suposar un problema per a aquelles persones preocupades per la privadesa."</string>
<string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"T\'has connectat a la xarxa encriptada <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
<string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"La connexió SIM de <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ara és més segura"</string>
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Informe d\'error"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Finalitza la sessió"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Captura de pantalla"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Informe d\'errors"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Es recopilarà informació sobre l\'estat actual del dispositiu i se t\'enviarà per correu electrònic. Passaran uns quants minuts des de l\'inici de l\'informe d\'errors fins al seu enviament, per la qual cosa et recomanem que tinguis paciència."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Informe interactiu"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona per desactivar la depuració sense fil."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"S\'ha activat el mode Agent de prova"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Si vols desactivar el mode Agent de prova, restableix les dades de fàbrica."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"S\'ha activat la consola de sèrie"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Afecta el rendiment. Per desactivar-la, comprova el bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"L\'MTE experimental s\'ha activat"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Deixa anar les tecles de volum. Per activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, torna a mantenir premudes totes dues tecles de volum durant 3 segons."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Tria la funció que vols utilitzar quan toquis el botó d\'accessibilitat:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Tria la funció que vols utilitzar amb el gest d\'accessibilitat (llisca cap amunt amb dos dits des de la part inferior de la pantalla):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Tria la funció que vols utilitzar amb el gest d\'accessibilitat (fes lliscar tres dits cap amunt des de la part inferior de la pantalla):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Per canviar entre funcions, mantén premut el botó d\'accessibilitat."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Per canviar entre funcions, llisca cap amunt amb dos dits i mantén premut."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Per canviar entre funcions, llisca cap amunt amb tres dits i mantén premut."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliació"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trucada en curs"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"S\'està filtrant una trucada entrant"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sense classificar"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícies"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomanacions"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Has definit la importància d\'aquestes notificacions."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Aquest missatge és important per les persones implicades."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificació d\'aplicació personalitzada"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de dreceres d\'accessibilitat en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Drecera d\'accessibilitat"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora l\'àrea de notificacions"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reprodueix o posa en pausa el contingut multimèdia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Creu direccional: amunt"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Creu direccional: avall"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Creu direccional: esquerra"</string>
@@ -2412,19 +2430,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espai privat"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"S\'ha amagat contingut sensible de les notificacions"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per motius de seguretat"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per seguretat"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"S\'ha connectat automàticament a un satèl·lit"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Pots enviar i rebre missatges sense una xarxa mòbil o Wi‑Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Com funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendent..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Torna a configurar Desbloqueig amb empremta digital"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionava correctament i s\'ha suprimit"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaven correctament i s\'han suprimit"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionava correctament i s\'ha suprimit. Torna a configurar-la per desbloquejar el telèfon amb l\'empremta digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaven correctament i s\'han suprimit. Torna a configurar-les per desbloquejar el telèfon amb l\'empremta digital."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Torna a configurar Desbloqueig facial"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"El teu model facial no funcionava correctament i s\'ha suprimit. Torna a configurar-lo per desbloquejar el telèfon amb la cara."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ara no"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma per a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Canvia d\'usuari"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silencia"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toca per silenciar el so"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index ad43a95..a5a42c3 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Hlášení chyb"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Ukončit relaci"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snímek obrazovky"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Hlášení chyb"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Shromažďuje informace o aktuálním stavu zařízení. Tyto informace je následně možné poslat v e-mailové zprávě, chvíli však potrvá, než bude hlášení o chybě připraveno k odeslání. Buďte prosím trpěliví."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktivní přehled"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Vyberte, chcete-li zakázat bezdrátové ladění."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Režim správce testů je aktivní"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Je zapnutá sériová konzole"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Toto má dopad na výkon. Chcete-li ji vypnout, zkontrolujte bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Je zapnuto experimentální MTE"</string>
@@ -1757,12 +1763,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvolněte tlačítka hlasitosti. Pokud chcete zapnout službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znovu tři sekundy podržte obě tlačítka hlasitosti."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Určete, jakou funkci aktivujete klepnutím na tlačítko přístupnosti:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Určete, jakou funkci aktivujete pomocí gesta přístupnosti (přejetí dvěma prsty ze spodní části obrazovky nahoru):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Určete, jakou funkci aktivujete pomocí gesta přístupnosti (přejetí třemi prsty ze spodní části obrazovky nahoru):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Chcete-li přepnout mezi funkcemi, podržte tlačítko přístupnosti."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Chcete-li přepnout mezi funkcemi, přejeďte nahoru dvěma prsty a podržte je."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Chcete-li přepnout mezi funkcemi, přejeďte nahoru třemi prsty a podržte je."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zvětšení"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1990,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Probíhající hovor"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Prověřování příchozího hovoru"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Neklasifikováno"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoakce"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sociální sítě"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Zprávy"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Doporučení"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Důležitost oznámení určujete vy."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Tato zpráva je důležitá kvůli lidem zapojeným do konverzace."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Vlastní oznámení aplikace"</string>
@@ -2194,6 +2210,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Výběr zkratky přístupnosti na obrazovce"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Zkratka přístupnosti"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zavřít panel oznámení"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Nabídka"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Přehrát/pozastavit média"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad nahoru"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad dolů"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad doleva"</string>
@@ -2420,12 +2438,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to funguje"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Čeká na vyřízení…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Opětovné nastavení odemknutí otiskem prstu"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správně a byl vymazán"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovaly správně a byly vymazány"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správně a byl vymazán. Pokud chcete telefon odemykat otiskem prstu, nastavte jej znovu."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovaly správně a byly vymazány. Pokud chcete telefon odemykat otiskem prstu, nastavte je znovu."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Nastavte odemknutí obličejem znovu"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Váš model obličeje nefungoval správně a byl vymazán. Pokud chcete telefon odemykat obličejem, nastavte jej znovu."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavit"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teď ne"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Budík pro uživatele <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Přepnout uživatele"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ztlumit"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Klepnutím ztlumíte zvuk"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e32b0b6..66ab048 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Fejlrapport"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Afslut sessionen"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Fejlrapport"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Der indsamles oplysninger om din enheds aktuelle status, der efterfølgende sendes i en mail. Der går lidt tid, fra fejlrapporten påbegyndes, til den er klar til at blive sendt. Tak for tålmodigheden."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv rapport"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Vælg for at deaktivere trådløs fejlretning."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tilstanden Testsele er aktiveret"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Gendan fabriksindstillingerne for at deaktivere tilstanden Testsele."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsollen er aktiveret"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Effektiviteten er påvirket. Deaktiver via bootloaderen."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentel MTE er aktiveret"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slip lydstyrkeknapperne. Du kan aktivere <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ved at holde begge lydstyrkeknapper nede igen i 3 sekunder."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen til hjælpefunktioner:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med to fingre):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med tre fingre):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Du kan skifte mellem funktioner ved at holde knappen til hjælpefunktioner nede."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Du kan skifte mellem funktioner ved at stryge opad med to fingre og holde dem nede."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Du kan skifte mellem funktioner ved at stryge opad med tre fingre og holde dem nede."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørrelse"</string>
<string name="user_switched" msgid="7249833311585228097">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skifter til <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Igangværende opkald"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Et indgående opkald screenes"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uden kategori"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoveringer"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Socialt"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheder"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Anbefalinger"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Du angiver, hvor vigtige disse notifikationer er."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Dette er vigtigt på grund af de personer, det handler om."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tilpasset appnotifikation"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Valg af genvej til hjælpefunktioner på skærmen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Genvej til hjælpefunktioner"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Luk notifikationspanel"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Afspil medie/sæt medie på pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad, op"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad, ned"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad, venstre"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Sådan fungerer det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer fingeroplåsning igen"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkede ikke optimalt og er derfor slettet"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkede ikke optimalt og er derfor slettet"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkede ikke optimalt og er derfor slettet. Konfigurer den igen for at bruge fingeroplåsning på din telefon."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkede ikke optimalt og er derfor slettet. Konfigurer dem igen for at bruge dit fingeraftryk til at låse din telefon op."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansigtsoplåsning igen"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Din ansigtsmodel virkede ikke optimalt og er derfor slettet. Konfigurer den igen for at bruge ansigtsoplåsning på din telefon."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm til <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Skift bruger"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Slå lyden fra"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tryk for at slå lyden fra"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ca858790..162b782 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Fehlerbericht"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Sitzung beenden"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Fehlerbericht"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Bei diesem Fehlerbericht werden Daten zum aktuellen Status deines Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte habe etwas Geduld."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiver Bericht"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Auswählen, um \"Debugging über WLAN\" zu deaktivieren."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test-Harnischmodus aktiviert"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serielle Konsole aktiviert"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Leistung wird beeinflusst. Überprüfe Bootloader zum Deaktivieren."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentelle MTE aktiviert"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lass die Lautstärketasten los. Halte zum Aktivieren von <xliff:g id="SERVICE_NAME">%1$s</xliff:g> beide Lautstärketasten noch einmal 3 Sekunden lang gedrückt."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Wähle eine Funktion aus, die verwendet wird, wenn du auf die Schaltfläche \"Bedienungshilfen\" tippst:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Wähle die Funktion aus, die mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit zwei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Wähle eine Funktion aus, die mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit drei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Wenn du zwischen den Funktionen wechseln möchtest, halte die Schaltfläche „Bedienungshilfen“ gedrückt."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Wenn du zwischen den Funktionen wechseln möchtest, wische mit zwei Fingern nach oben und halte."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Wenn du zwischen den Funktionen wechseln möchtest, wische mit drei Fingern nach oben und halte."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergrößerung"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Wechseln zu <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktueller Anruf"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filter für eingehenden Anruf"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Unkategorisiert"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Werbeaktionen"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Soziale Netzwerke"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Neuigkeiten"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Empfehlungen"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Du hast die Wichtigkeit dieser Benachrichtigungen festgelegt."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Diese Benachrichtigung ist aufgrund der beteiligten Personen wichtig."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Benutzerdefinierte App-Benachrichtigung"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Auswahl für Kurzbefehle für Bildschirmbedienungshilfen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kurzbefehl für Bedienungshilfen"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Benachrichtigungsleiste schließen"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Medien wiedergeben/pausieren"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Steuerkreuz nach oben"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Steuerkreuz nach unten"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Steuerkreuz nach links"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Vertrauliches Profil"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Vertrauliche Benachrichtigungsinhalte ausgeblendet"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-Inhalte werden aus Sicherheitsgründen bei der Bildschirmfreigabe ausgeblendet"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Aus Sicherheitsgründen werden bei der Bildschirmfreigabe App-Inhalte ausgeblendet"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch mit Satellit verbunden"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Du kannst Nachrichten ohne Mobilfunknetz oder WLAN senden und empfangen"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"So funktionierts"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ausstehend…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Entsperrung per Fingerabdruck neu einrichten"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> hat nicht einwandfrei funktioniert und wurde gelöscht"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> haben nicht einwandfrei funktioniert und wurden gelöscht"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> hat nicht einwandfrei funktioniert und wurde gelöscht. Richte ihn noch einmal ein, um dein Smartphone per Fingerabdruck zu entsperren."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> haben nicht einwandfrei funktioniert und wurden gelöscht. Richte sie noch einmal ein, um dein Smartphone per Fingerabdruck zu entsperren."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Entsperrung per Gesichtserkennung neu einrichten"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Dein Gesichtsmodell hat nicht einwandfrei funktioniert und wurde gelöscht. Richte es noch einmal ein, um dein Smartphone per Gesichtserkennung zu entsperren."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Einrichten"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nicht jetzt"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Wecker für <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Nutzer wechseln"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Stummschalten"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Zum Stummschalten tippen"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index cb1d3b1..0e0a5828 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Αναφορά σφαλμάτων"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Λήξη περιόδου σύνδεσης"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Στιγμιότυπο οθόνης"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Αναφορά σφάλματος"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Θα συλλέξει πληροφορίες σχετικά με την τρέχουσα κατάσταση της συσκευής σας και θα τις στείλει μέσω μηνύματος ηλεκτρονικού ταχυδρομείου. Απαιτείται λίγος χρόνος για τη σύνταξη της αναφοράς σφάλματος και την αποστολή της. Κάντε λίγη υπομονή."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Διαδραστική αναφορά"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Επιλέξτε, για να απενεργοποιήσετε τον ασύρματο εντοπισμό σφαλμάτων."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Η λειτουργία περιβάλλοντος δοκιμών ενεργοποιήθηκε"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Εκτελέστε επαναφορά εργοστασιακών ρυθμίσεων για να απενεργοποιήσετε τη λειτουργία περιβάλλοντος δοκιμών."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Η σειριακή κονσόλα ενεργοποιήθηκε"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Η απόδοση επηρεάζεται. Για απενεργοποίηση, επιλέξτε το πρόγραμμα φόρτωσης εκκίνησης."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Ενεργοποιήθηκε το πειραματικό MTE"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Αφήστε τα κουμπιά έντασης ήχου. Για να ενεργοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, πατήστε ξανά παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού προσβασιμότητας:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με δύο δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με τρία δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Για εναλλαγή μεταξύ λειτουργιών, αγγίξτε παρατεταμένα το κουμπί προσβασιμότητας."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Για εναλλαγή μεταξύ λειτουργιών, σύρετε παρατεταμένα με δύο δάχτυλα προς τα επάνω."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Για εναλλαγή μεταξύ λειτουργιών, σύρετε παρατεταμένα με τρία δάχτυλα προς τα επάνω."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Μεγιστοποίηση"</string>
<string name="user_switched" msgid="7249833311585228097">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Κλήση σε εξέλιξη"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Διαλογή εισερχόμενης κλήσης"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Μη κατηγοριοποιημένο"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Προωθήσεις"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Κοινωνικά δίκτυα"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Ειδήσεις"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Προτάσεις"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Μπορείτε να ρυθμίσετε τη βαρύτητα αυτών των ειδοποιήσεων."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Αυτό είναι σημαντικό λόγω των ατόμων που συμμετέχουν."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Προσαρμοσμένη ειδοποίηση εφαρμογής"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Επιλογέας συντόμευσης οθόνης για την προσβασιμότητα"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Συντόμευση προσβασιμότητας"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Παράβλεψη πλαισίου σκίασης ειδοποιήσεων"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Μενού"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Αναπαραγωγή/παύση μέσων"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad επάνω"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad κάτω"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad αριστερά"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Πώς λειτουργεί"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Σε εκκρεμότητα…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Το δακτυλικό αποτύπωμα <xliff:g id="FINGERPRINT">%s</xliff:g> δεν λειτουργούσε καλά και διαγράφηκε"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Τα δακτυλικά αποτυπώματα <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> δεν λειτουργούσαν καλά και διαγράφηκαν"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Το δακτυλικό αποτύπωμα <xliff:g id="FINGERPRINT">%s</xliff:g> δεν λειτουργούσε καλά και διαγράφηκε. Ρυθμίστε το ξανά για να ξεκλειδώνετε το τηλέφωνο με το δακτυλικό αποτύπωμά σας."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Τα δακτυλικά αποτυπώματα <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> δεν λειτουργούσαν καλά και διαγράφηκαν. Ρυθμίστε τα ξανά για να ξεκλειδώνετε το τηλέφωνο με το δακτυλικό αποτύπωμά σας."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με το πρόσωπο"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Το μοντέλο προσώπου δεν λειτουργούσε καλά και διαγράφηκε. Ρυθμίστε το ξανά για να ξεκλειδώνετε το τηλέφωνο με το πρόσωπό σας."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ρύθμιση"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Όχι τώρα"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Ξυπνητήρι για τον χρήστη <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Εναλλαγή χρήστη"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Σίγαση"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Πατήστε για σίγαση του ήχου"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index e748648..73081b8 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Bug report"</string>
<string name="global_action_logout" msgid="6093581310002476511">"End session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Bug report"</string>
<string name="bugreport_message" msgid="5212529146119624326">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interactive report"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the Accessibility button."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorised"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media play/pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad up"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad down"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad left"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index b19bdf9..00b39a9 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Bug report"</string>
<string name="global_action_logout" msgid="6093581310002476511">"End session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Bug report"</string>
<string name="bugreport_message" msgid="5212529146119624326">"This will collect information about your current device state, to send as an e-mail message. It will take a little time from starting the bug report until it is ready to be sent; please be patient."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interactive report"</string>
@@ -1411,6 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Wrong HSUM build configuration"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"The Headless System User Mode state of this device differs from its build configuration. Please factory reset the device."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for 3 seconds."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the accessibility button:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the accessibility button."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choose a feature"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choose a feature"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choose a feature"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open next time you tap the accessibility button"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1975,6 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ongoing call"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorized"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2191,6 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen Accessibility Shortcut Chooser"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility Shortcut"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss Notification Shade"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media Play/Pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Up"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Down"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Left"</string>
@@ -2417,12 +2427,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 818614a..0fff77a 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Bug report"</string>
<string name="global_action_logout" msgid="6093581310002476511">"End session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Bug report"</string>
<string name="bugreport_message" msgid="5212529146119624326">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interactive report"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the Accessibility button."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorised"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media play/pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad up"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad down"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad left"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a58f731..ba7bc5f 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Bug report"</string>
<string name="global_action_logout" msgid="6093581310002476511">"End session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Bug report"</string>
<string name="bugreport_message" msgid="5212529146119624326">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interactive report"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the Accessibility button."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorised"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media play/pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad up"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad down"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad left"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index cb9bbf5..2798d03 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Bug report"</string>
<string name="global_action_logout" msgid="6093581310002476511">"End session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Bug report"</string>
<string name="bugreport_message" msgid="5212529146119624326">"This will collect information about your current device state, to send as an e-mail message. It will take a little time from starting the bug report until it is ready to be sent; please be patient."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interactive report"</string>
@@ -1411,6 +1413,8 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+ <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Wrong HSUM build configuration"</string>
+ <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"The Headless System User Mode state of this device differs from its build configuration. Please factory reset the device."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1759,12 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for 3 seconds."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the accessibility button:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch & hold the accessibility button."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+ <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choose a feature"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choose a feature"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choose a feature"</string>
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open next time you tap the accessibility button"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
<string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1975,6 +1979,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ongoing call"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorized"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2191,6 +2199,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen Accessibility Shortcut Chooser"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility Shortcut"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss Notification Shade"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media Play/Pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Up"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Down"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Left"</string>
@@ -2417,12 +2427,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 94591ea8..543afeb 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Informe de errores"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Finalizar sesión"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Captura de pantalla"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Informe de errores"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Se recopilará información sobre el estado actual de tu dispositivo, que se enviará por correo. Pasarán unos minutos desde que se inicie el informe de errores hasta que se envíe, por lo que te recomendamos que tengas paciencia."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Informe interactivo"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona para inhabilitar la depuración inalámbrica."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Se habilitó el modo de agente de prueba"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Se habilitó la consola en serie"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Afecta el rendimiento. Para inhabilitarla, verifica el bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental habilitada"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vuelve a mantener presionadas las teclas de volumen durante 3 segundos."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Elige una función para usar cuando pulses el botón accesibilidad:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Elige la función que se usará cuando realices el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Elige la función que se usará cuando realices el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para cambiar entre funciones, mantén presionado el botón de accesibilidad."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para cambiar de función, desliza dos dedos hacia arriba y mantén presionada la pantalla."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para cambiar de función, desliza tres dedos hacia arriba y mantén presionada la pantalla."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sin categoría"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promociones"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Redes sociales"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Noticias"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendaciones"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Estableciste la importancia de estas notificaciones."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Es importante debido a las personas involucradas."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de app personalizada"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector del acceso directo de accesibilidad en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Descartar panel de notificaciones"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproducir o pausar contenido multimedia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pad direccional: arriba"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pad direccional: abajo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pad direccional: izquierda"</string>
@@ -2419,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vuelve a configurar el Desbloqueo con huellas dactilares"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Se borró <xliff:g id="FINGERPRINT">%s</xliff:g> porque no funcionaba correctamente"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Se borraron <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> porque no funcionaban correctamente"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Se borró <xliff:g id="FINGERPRINT">%s</xliff:g> porque no funcionaba correctamente. Vuelve a configurarla para desbloquear el teléfono con la huella dactilar."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Se borraron <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> porque no funcionaban correctamente. Vuelve a configurarlas para desbloquear el teléfono con la huella dactilar."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vuelve a configurar el Desbloqueo facial"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Se borró tu modelo de rostro porque no funcionaba correctamente. Vuelve a configurarlo para desbloquear el teléfono con el rostro."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Presiona para silenciar el sonido"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 2634494..0a153ba 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Informe de errores"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Finalizar sesión"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Captura de pantalla"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Informe de errores"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Se recopilará información sobre el estado actual de tu dispositivo y se enviará por correo electrónico. Pasarán unos minutos desde que empiece a generarse el informe de errores hasta que se envíe."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Informe interactivo"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Toca para desactivar la depuración inalámbrica."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo de agente de prueba habilitado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Se ha habilitado la consola en serie"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Afecta al rendimiento. Para inhabilitarlo, comprueba el bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental habilitado"</string>
@@ -1748,7 +1754,7 @@
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hecho"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
- <string name="color_inversion_feature_name" msgid="2672824491933264951">"Invertir colores"</string>
+ <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversión de colores"</string>
<string name="color_correction_feature_name" msgid="7975133554160979214">"Corrección de color"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo Una mano"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas las dos teclas de volumen de nuevo durante 3 segundos."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Selecciona la función que se utilizará cuando toques el botón de accesibilidad:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Elige la función que se utilizará con el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Elige la función que se utilizará con el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para cambiar de una función a otra, mantén pulsado el botón de accesibilidad."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para cambiar de una función a otra, desliza hacia arriba con dos dedos y mantén pulsada la pantalla."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para cambiar de una función a otra, desliza tres dedos hacia arriba y mantén pulsada la pantalla."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sin clasificar"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promociones"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Noticias"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendaciones"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Tú determinas la importancia de estas notificaciones."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Esto es importante por los usuarios implicados."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de aplicación personalizada"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Menú de acceso directo de accesibilidad en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Cerrar pantalla de notificaciones"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Pausar/Reproducir contenido multimedia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Cruceta: arriba"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Cruceta: abajo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Cruceta: izquierda"</string>
@@ -2412,19 +2430,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espacio privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Contenido sensible de la notificación oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por motivos de seguridad"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por seguridad"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automáticamente al satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes sin una red móvil o Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura Desbloqueo con huella digital de nuevo"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionaba correctamente y se ha eliminado"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaban correctamente y se han eliminado"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionaba correctamente y se ha eliminado. Configúrala de nuevo para desbloquear el teléfono con la huella digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaban correctamente y se han eliminado. Configúralas de nuevo para desbloquear el teléfono con la huella digital."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configura Desbloqueo facial de nuevo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Tu modelo facial no funcionaba correctamente y se ha eliminado. Configúralo de nuevo para desbloquear el teléfono con la cara."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toca para silenciar el sonido"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 9c9ff1b..4b81448c 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Veaaruanne"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Seansi lõpp"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Ekraanipilt"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Veaaruanne"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Nii kogutakse teavet teie seadme praeguse oleku kohta, et saata see meilisõnumina. Enne kui saate veaaruande ära saata, võtab selle loomine natuke aega; varuge kannatust."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interakt. aruanne"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Valige juhtmevaba silumise keelamiseks."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testrakendirežiim on lubatud"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Testrakendirežiimi keelamiseks taastage tehaseseaded."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Seeriakonsool on lubatud"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"See mõjutab toimivust. Keelamiseks kontrollige käivituslaadurit."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Katseline MTE on lubatud"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vabastage helitugevuse klahvid. Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisselülitamiseks vajutage uuesti mõlemat helitugevuse klahvi ja hoidke neid 3 sekundit all."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Valige, millist funktsiooni kasutada, kui vajutate juurdepääsetavuse nuppu:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kahe sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kolme sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funktsioonide vahel vahetamiseks vajutage juurdepääsetavuse nuppu pikalt."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funktsioonide vahel vahetamiseks pühkige kahe sõrmega üles ja hoidke."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funktsioonide vahel vahetamiseks pühkige kolme sõrmega üles ja hoidke."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurendus"</string>
<string name="user_switched" msgid="7249833311585228097">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käimasolev kõne"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Sissetuleva kõne filtreerimine"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Kategoriseerimata"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Kampaaniad"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Suhtlus"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Uudised"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Soovitused"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Teie määrasite nende märguannete tähtsuse."</string>
<string name="importance_from_person" msgid="4235804979664465383">"See on tähtis osalevate inimeste tõttu."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Rakenduse kohandatud märguanne"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekraanil kuvatav juurdepääsetavuse otsetee valija"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Juurdepääsetavuse otsetee"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Loobu märguandealast"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menüü"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Meedia esitamine/peatamine"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Suunaklahvistiku ülesnool"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Suunaklahvistiku allanool"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Suunaklahvistiku vasaknool"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privaatne ruum"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Märguande delikaatne sisu peideti"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamises turvalisuse huvides peidetud"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamisel turvalisuse huvides peidetud"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Satelliidiga loodi automaatselt ühendus"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Teil on võimalik sõnumeid saata ja vastu võtta ilma mobiilside- ja WiFi-võrguta"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Tööpõhimõtted"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ootel …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Seadistage sõrmejäljega avamine uuesti"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei töötanud hästi ja kustutati"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei töötanud hästi ning kustutati"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei töötanud hästi ja kustutati. Telefoni sõrmejäljega avamiseks seadistage see uuesti."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei töötanud hästi ning kustutati. Telefoni sõrmejäljega avamiseks seadistage need uuesti."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Seadistage näoga avamine uuesti"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Teie näomudel ei töötanud hästi ja kustutati. Telefoni näoga avamiseks seadistage see uuesti."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Seadista"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Mitte praegu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Äratus kasutajale <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Vaheta kasutajat"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Vaigista"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Puudutage heli vaigistamiseks"</string>
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index d2f77eb..16b956e 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Akatsen txostena"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Amaitu saioa"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Pantaila-argazkia"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Akatsen txostena"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Gailuaren oraingo egoerari buruzko informazioa bilduko da, mezu elektroniko gisa bidaltzeko. Minutu batzuk igaroko dira akatsen txostena sortzen hasten denetik bidaltzeko prest egon arte. Itxaron, mesedez."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Txosten dinamikoa"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Hautatu hau hari gabeko arazketa desgaitzeko."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Proba-materialeko modua gaitu da"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serie-kontsola gaituta"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Errendimenduari eragiten dio. Desgaitzeko, joan abiarazlera."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE esperimentala gaituta dago"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Askatu bolumen-botoiak. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatzeko, eduki sakatuta berriro bi bolumen-botoiak hiru segundoz."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, bi hatz pantailaren behealdetik gora pasatzean):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, hiru hatz pantailaren behealdetik gora pasatzean):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Eginbide batetik bestera aldatzeko, eduki sakatuta Erabilerraztasuna botoia."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Eginbide batetik bestera aldatzeko, pasatu bi hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Eginbide batetik bestera aldatzeko, pasatu hiru hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Lupa"</string>
<string name="user_switched" msgid="7249833311585228097">"Erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"\"<xliff:g id="NAME">%1$s</xliff:g>\" erabiltzailera aldatzen…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Deia abian da"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Sarrerako dei bat bistaratzen"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Kategoriarik gabea"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promozioak"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sare sozialak"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Albisteak"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Gomendioak"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Garrantzitsua da eragiten dien pertsonengatik."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Aplikazio-jakinarazpen pertsonalizatua"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pantailako erabilerraztasun-lasterbideen hautatzailea"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Erabilerraztasun-lasterbidea"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Baztertu jakinarazpenen panela"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menua"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Erreproduzitu/Pausatu multimedia-elementua"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Norabide-kontrolagailuko goiko botoia"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Norabide-kontrolagailuko beheko botoia"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Norabide-kontrolagailuko ezkerreko botoia"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Nola funtzionatzen du?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ezabatu egin da, ez zuelako ondo funtzionatzen"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ezabatu egin dira, ez zutelako ondo funtzionatzen"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ezabatu egin da, ez zuelako ondo funtzionatzen. Telefonoa hatz-markarekin desblokeatzeko, konfigura ezazu berriro."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ezabatu egin dira, ez zutelako ondo funtzionatzen. Telefonoa hatz-markarekin desblokeatzeko, konfigura itzazu berriro."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguratu berriro aurpegi bidez desblokeatzeko eginbidea"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Aurpegi-eredua ezabatu egin da, ez zuelako ondo funtzionatzen. Telefonoa aurpegiarekin desblokeatzeko, konfigura ezazu berriro."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfiguratu"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Orain ez"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> erabiltzailearentzako alarma"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Aldatu erabiltzailea"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desaktibatu audioa"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Sakatu audioa desaktibatzeko"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d761c8a..71e7760 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -82,7 +82,7 @@
<string name="RestrictedStateContent" msgid="7693575344608618926">"شرکت مخابراتی شما موقتاً آن را خاموش کرده است"</string>
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"شرکت مخابراتیتان موقتاً آن را برای سیمکارت <xliff:g id="SIMNUMBER">%d</xliff:g> خاموش کرده است"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"شبکه تلفن همراه دردسترس نیست"</string>
- <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، ضربه بزنید."</string>
+ <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، تکضرب بزنید."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"تماس اضطراری امکانپذیر نیست"</string>
<string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"برای برقراری تماس اضطراری به شبکه تلفن همراه نیاز دارید"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"هشدارها"</string>
@@ -204,7 +204,7 @@
<string name="private_space_deleted_by_admin" msgid="1484365588862066939">"فضای خصوصی حذف شد"</string>
<string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"سازمان شما اجازه نمیدهد در این دستگاه مدیریتشده فضای خصوصی وجود داشته باشد."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"دستگاه مدیریت میشود"</string>
- <string name="network_logging_notification_text" msgid="1327373071132562512">"سازمانتان این دستگاه را مدیریت میکند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، ضربه بزنید."</string>
+ <string name="network_logging_notification_text" msgid="1327373071132562512">"سازمانتان این دستگاه را مدیریت میکند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، تکضرب بزنید."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"برنامهها میتوانند به مکانتان دسترسی پیدا کنند"</string>
<string name="location_changed_notification_text" msgid="7158423339982706912">"برای کسب اطلاعات بیشتر با سرپرست فناوری اطلاعات تماس بگیرید"</string>
<string name="geofencing_service" msgid="3826902410740315456">"سرویس حصارکشی جغرافیایی"</string>
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"گزارش اشکال"</string>
<string name="global_action_logout" msgid="6093581310002476511">"پایان جلسه"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"نماگرفت"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"گزارش اشکال"</string>
<string name="bugreport_message" msgid="5212529146119624326">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمعآوری میکند تا بهصورت پیام ایمیل ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان میبرد؛ لطفاً کمی صبر کنید."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"گزارش تعاملی"</string>
@@ -309,7 +311,7 @@
<string name="notification_channel_display" msgid="6905032605735615090">"نمایشگر"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحال استفاده کردن از باتری است"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> برنامه درحال استفاده کردن از باتری هستند"</string>
- <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
+ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"برای جزئیات مربوط به مصرف باتری و داده، تکضرب بزنید"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>، <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"حالت ایمن"</string>
<string name="android_system_label" msgid="5974767339591067210">"سیستم Android"</string>
@@ -356,7 +358,7 @@
<string name="capability_title_canControlMagnification" msgid="7701572187333415795">"کنترل درشتنمایی نمایشگر"</string>
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"موقعیت و سطح بزرگنمایی نمایشگر را کنترل کنید."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"اجرای اشارهها"</string>
- <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"میتوانید ضربه بزنید، انگشتتان را تند بکشید، انگشتانتان را به هم نزدیک یا از هم دور کنید و اشارههای دیگری اجرا کنید."</string>
+ <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"میتوانید تکضرب بزنید، انگشتتان را تند بکشید، انگشتانتان را به هم نزدیک یا از هم دور کنید و اشارههای دیگری اجرا کنید."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"اشارههای اثر انگشت"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"میتواند اشارههای اجراشده روی حسگر اثرانگشت دستگاه را ثبت کند."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"گرفتن نماگرفت"</string>
@@ -701,7 +703,7 @@
<string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"وقتی چهرهتان تشخیص داده نمیشود، مثل زمانی که نور کافی نیست، از «قفلگشایی با اثر انگشت» استفاده کنید"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"قفلگشایی با چهره"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"مشکل در «قفلگشایی با چهره»"</string>
- <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"برای حذف مدل چهرهتان ضربه بزنید، سپس چهرهتان را دوباره اضافه کنید"</string>
+ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"برای حذف مدل چهرهتان تکضرب بزنید، سپس چهرهتان را دوباره اضافه کنید"</string>
<string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"برای استفاده از «قفلگشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات > حریم خصوصی» روشن کنید"</string>
<string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"قفلگشایی با اثر انگشت"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"امکان استفاده از حسگر اثر انگشت وجود ندارد"</string>
@@ -847,7 +849,7 @@
<string name="policydesc_resetPassword" msgid="4626419138439341851">"قفل صفحه را تغییر میدهد."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"قفل کردن صفحه"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"نحوه و زمان قفل شدن صفحه را کنترل میکند."</string>
- <string name="policylab_wipeData" msgid="1359485247727537311">"پاک کردن تمام دادهها"</string>
+ <string name="policylab_wipeData" msgid="1359485247727537311">"پاک کردن همه دادهها"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"با انجام بازنشانی دادههای کارخانه، دادههای رایانهٔ لوحی بدون هشدار پاک میشود."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"دادههای دستگاه Android TV شما، بدون نشان داده شدن هشدار و با انجام بازنشانی دادههای کارخانه، پاک میشود."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"دادههای سیستم اطلاعات-سرگرمی بدون هشدار و با انجام بازنشانی دادههای کارخانه پاک میشود."</string>
@@ -986,7 +988,7 @@
<string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"PUK و پین کد جدید را تایپ کنید"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"کد PUK"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"پین کد جدید"</string>
- <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"برای تایپ گذرواژه ضربه بزنید"</font></string>
+ <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"برای تایپ گذرواژه تکضرب بزنید"</font></string>
<string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"برای بازکردن قفل، گذرواژه را وارد کنید"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"برای بازکردن قفل، پین را تایپ کنید"</string>
<string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"پین کد اشتباه است."</string>
@@ -1198,7 +1200,7 @@
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"فضای ذخیرهسازی سیستم کافی نیست. اطمینان حاصل کنید که دارای ۲۵۰ مگابایت فضای خالی هستید و سیستم را راهاندازی مجدد کنید."</string>
<string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> در حال اجرا است"</string>
- <string name="app_running_notification_text" msgid="5120815883400228566">"برای کسب اطلاعات بیشتر یا توقف برنامه ضربه بزنید."</string>
+ <string name="app_running_notification_text" msgid="5120815883400228566">"برای کسب اطلاعات بیشتر یا توقف برنامه تکضرب بزنید."</string>
<string name="ok" msgid="2646370155170753815">"تأیید"</string>
<string name="cancel" msgid="6908697720451760115">"لغو"</string>
<string name="yes" msgid="9069828999585032361">"تأیید"</string>
@@ -1289,15 +1291,15 @@
<string name="android_preparing_apk" msgid="589736917792300956">"آمادهسازی <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"درحال آغاز کردن برنامهها."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"درحال اتمام راهاندازی."</string>
- <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحهنمایش را خاموش میکند.\n\nهنگام راهاندازی اثر انگشت، آرام ضربه بزنید."</string>
+ <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحهنمایش را خاموش میکند.\n\nهنگام راهاندازی اثر انگشت، آرام تکضرب بزنید."</string>
<string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"برای اتمام راهاندازی، صفحه را خاموش کنید"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"خاموش کردن"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"تأیید اثر انگشت را ادامه میدهید؟"</string>
- <string name="fp_power_button_bp_message" msgid="2983163038168903393">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحهنمایش را خاموش میکند.\n\nبرای تأیید اثر انگشتتان، آرام ضربه بزنید."</string>
+ <string name="fp_power_button_bp_message" msgid="2983163038168903393">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحهنمایش را خاموش میکند.\n\nبرای تأیید اثر انگشتتان، آرام تکضرب بزنید."</string>
<string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"خاموش کردن صفحه"</string>
<string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"ادامه"</string>
<string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
- <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"برای برگشتن به بازی، ضربه بزنید"</string>
+ <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"برای برگشتن به بازی، تکضرب بزنید"</string>
<string name="heavy_weight_switcher_title" msgid="3861984210040100886">"انتخاب بازی"</string>
<string name="heavy_weight_switcher_text" msgid="6814316627367160126">"برای عملکرد بهتر، هربار فقط یکی از این بازیها را میتوان باز کرد."</string>
<string name="old_app_action" msgid="725331621042848590">"به <xliff:g id="OLD_APP">%1$s</xliff:g> برگردید"</string>
@@ -1305,19 +1307,19 @@
<string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> بدون ذخیره شدن بسته میشود"</string>
<string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه فراتر رفت"</string>
<string name="dump_heap_ready_notification" msgid="2302452262927390268">"رونوشت حافظه آزاد<xliff:g id="PROC">%1$s</xliff:g> آماده است"</string>
- <string name="dump_heap_notification_detail" msgid="8431586843001054050">"رونوشت حافظه جمعآوری شد. برای همرسانی ضربه بزنید."</string>
+ <string name="dump_heap_notification_detail" msgid="8431586843001054050">"رونوشت حافظه جمعآوری شد. برای همرسانی تکضرب بزنید."</string>
<string name="dump_heap_title" msgid="4367128917229233901">"رونوشت حافظه آزاد به اشتراک گذاشته شود؟"</string>
<string name="dump_heap_text" msgid="1692649033835719336">"فرآیند <xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه پردازش خود،<xliff:g id="SIZE">%2$s</xliff:g>، فراتر رفته است. رونوشت حافظه آزادی دردسترستان است که با برنامهنویس آن به اشتراک بگذارید. مراقب باشید: این رونوشت حافظه آزاد میتواند حاوی هرنوع اطلاعات شخصی شما باشد که برنامه به آن دسترسی دارد."</string>
<string name="dump_heap_system_text" msgid="6805155514925350849">"فرآیند <xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه پردازش خود <xliff:g id="SIZE">%2$s</xliff:g> فراتر رفته است. یک رونوشت حافظه آزاد برای شما برای همرسانی دردسترس است. مواظب باشید: این رونوشت حافظه آزاد میتواند حاوی هر نوع اطلاعات شخصی شما باشد که فرآیند به آن دسترسی دارد که ممکن است شامل چیزهایی باشد که تایپ کردهاید."</string>
<string name="dump_heap_ready_text" msgid="5849618132123045516">"رونوشت حافظه آزاد فرآیند<xliff:g id="PROC">%1$s</xliff:g> برای همرسانی دردسترس شما قرار دارد. مراقب باشید: ممکن است این رونوشت حافظه آزاد حاوی اطلاعات شخصی حساس باشد که فرآیند به آن دسترسی دارد و ممکن است شامل چیزهایی باشد که تایپ کردهاید."</string>
<string name="sendText" msgid="493003724401350724">"انتخاب یک عملکرد برای نوشتار"</string>
- <string name="volume_ringtone" msgid="134784084629229029">"میزان صدای زنگ"</string>
+ <string name="volume_ringtone" msgid="134784084629229029">"صدای زنگ"</string>
<string name="volume_music" msgid="7727274216734955095">"میزان صدای رسانه"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"پخش از طریق بلوتوث"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"آهنگ زنگ روی بیصدا تنظیم شد"</string>
<string name="volume_call" msgid="7625321655265747433">"صدا حینِ تماس"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"میزان صدای تماس بلوتوث"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"میزان صدای زنگ"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"صدای زنگ هشدار"</string>
<string name="volume_notification" msgid="6864412249031660057">"میزان صدای اعلان"</string>
<string name="volume_unknown" msgid="4041914008166576293">"میزان صدا"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"میزان صدای بلوتوث"</string>
@@ -1337,12 +1339,12 @@
<!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
<skip />
<string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> به اینترنت دسترسی ندارد"</string>
- <string name="wifi_no_internet_detailed" msgid="634938444133558942">"برای گزینهها ضربه بزنید"</string>
+ <string name="wifi_no_internet_detailed" msgid="634938444133558942">"برای گزینهها تکضرب بزنید"</string>
<string name="mobile_no_internet" msgid="4014455157529909781">"شبکه تلفن همراه به اینترنت دسترسی ندارد"</string>
<string name="other_networks_no_internet" msgid="6698711684200067033">"شبکه به اینترنت دسترسی ندارد"</string>
<string name="private_dns_broken_detailed" msgid="3709388271074611847">"سرور DNS خصوصی قابل دسترسی نیست"</string>
<string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> اتصال محدودی دارد"</string>
- <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"بههرصورت، برای اتصال ضربه بزنید"</string>
+ <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"بههرصورت، برای اتصال تکضرب بزنید"</string>
<string name="network_switch_metered" msgid="1531869544142283384">"به <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> تغییر کرد"</string>
<string name="network_switch_metered_detail" msgid="1358296010128405906">"وقتی <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> به اینترنت دسترسی نداشته باشد، دستگاه از <xliff:g id="NEW_NETWORK">%1$s</xliff:g> استفاده میکند. ممکن است هزینههایی اعمال شود."</string>
<string name="network_switch_metered_toast" msgid="501662047275723743">"از <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> به <xliff:g id="NEW_NETWORK">%2$s</xliff:g> تغییر کرد"</string>
@@ -1381,7 +1383,7 @@
<string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"برای فعال کردن سیمکارت جدیدتان، برنامه <xliff:g id="APP_NAME">%1$s</xliff:g> را بارگیری کنید"</string>
<string name="install_carrier_app_notification_button" msgid="6257740533102594290">"بارگیری برنامه"</string>
<string name="carrier_app_notification_title" msgid="5815477368072060250">"سیمکارت جدید جاگذاری شد"</string>
- <string name="carrier_app_notification_text" msgid="6567057546341958637">"برای تنظیم آن ضربه بزنید"</string>
+ <string name="carrier_app_notification_text" msgid="6567057546341958637">"برای تنظیم آن تکضرب بزنید"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"تنظیم زمان"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"تاریخ تنظیم"</string>
<string name="date_time_set" msgid="4603445265164486816">"تنظیم"</string>
@@ -1399,24 +1401,28 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI ازطریق USB روشن شد"</string>
<string name="usb_uvc_notification_title" msgid="2030032862673400008">"دستگاه بهعنوان «وببین» متصل شده است"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"وسیله جانبی USB متصل است"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"برای گزینههای بیشتر ضربه بزنید."</string>
- <string name="usb_power_notification_message" msgid="7284765627437897702">"درحال شارژ کردن دستگاه متصلشده. برای گزینههای بیشتر، ضربه بزنید."</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"برای گزینههای بیشتر تکضرب بزنید."</string>
+ <string name="usb_power_notification_message" msgid="7284765627437897702">"درحال شارژ کردن دستگاه متصلشده. برای گزینههای بیشتر، تکضرب بزنید."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"لوازم جانبی صوتی آنالوگ شناسایی شد"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"دستگاه متصلشده با این تلفن سازگار نیست. روی اطلاعات بیشتر، ضربه بزنید."</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"دستگاه متصلشده با این تلفن سازگار نیست. روی اطلاعات بیشتر، تکضرب بزنید."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"اشکالزدایی USB متصل شد"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"برای خاموش کردن اشکالزدایی USB ضربه بزنید"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"برای خاموش کردن اشکالزدایی USB تکضرب بزنید"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"اشکالزدایی بیسیم متصل است"</string>
- <string name="adbwifi_active_notification_message" msgid="930987922852867972">"برای خاموش کردن اشکالزدایی بیسیم ضربه بزنید"</string>
+ <string name="adbwifi_active_notification_message" msgid="930987922852867972">"برای خاموش کردن اشکالزدایی بیسیم تکضرب بزنید"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"برای غیرفعال کردن اشکالزدایی بیسیم انتخاب کنید."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"«حالت مجموعه دادههای تست» فعال شد"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"برای غیرفعال کردن «حالت مجموعه دادههای تست»، بازنشانی کارخانهای کنید."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"کنسول سریال فعال است"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"عملکرد تحتتأثیر قرار گرفته است. برای غیرفعال کردن، bootloader را بررسی کنید."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE آزمایشی فعال شد"</string>
<string name="mte_override_notification_message" msgid="2441170442725738942">"شاید عملکرد و پایداری تحت تأثیر قرار بگیرند. برای غیرفعال کردن، بازراهاندازی کنید. اگر بااستفاده از arm64.memtag.bootctl فعال شده است، پیشاز بازراهاندازی مقدار آن را روی هیچکدام تنظیم کنید."</string>
<string name="usb_contaminant_detected_title" msgid="4359048603069159678">"مایعات یا خاکروبه در درگاه USB"</string>
- <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"درگاه USB بهطور خودکار غیرفعال شده است. برای اطلاعات بیشتر، ضربه بزنید."</string>
+ <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"درگاه USB بهطور خودکار غیرفعال شده است. برای اطلاعات بیشتر، تکضرب بزنید."</string>
<string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"میتوان از درگاه USB استفاده کرد"</string>
<string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"تلفن دیگر وجود مایعات یا خاکروبه را تشخیص نمیدهد."</string>
<string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"درحال گرفتن گزارش اشکال…"</string>
@@ -1430,7 +1436,7 @@
<string name="hardware" msgid="3611039921284836033">"استفاده از صفحهکلید مجازی"</string>
<string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"پیکربندی <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
<string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"پیکربندی صفحهکلیدهای فیزیکی"</string>
- <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"برای انتخاب زبان و چیدمان ضربه بزنید"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"برای انتخاب زبان و چیدمان تکضرب بزنید"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"نمایش روی سایر برنامهها"</string>
@@ -1443,19 +1449,19 @@
<string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"درحال تجزیهوتحلیل فضای ذخیرهسازی رسانه"</string>
<string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> جدید"</string>
<string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> کار نمیکند"</string>
- <string name="ext_media_new_notification_message" msgid="6095403121990786986">"برای راهاندازی ضربه بزنید"</string>
+ <string name="ext_media_new_notification_message" msgid="6095403121990786986">"برای راهاندازی تکضرب بزنید"</string>
<string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"برای راهاندازی، انتخاب کنید"</string>
- <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"شاید لازم باشد دستگاه را دوباره قالببندی کنید. برای خارج کردن، ضربه بزنید."</string>
+ <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"شاید لازم باشد دستگاه را دوباره قالببندی کنید. برای خارج کردن، تکضرب بزنید."</string>
<string name="ext_media_ready_notification_message" msgid="7509496364380197369">"برای ذخیره کردن عکس، ویدیو، موسیقی و غیره"</string>
<string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"فایلهای رسانهای را مرور کنید"</string>
<string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"مشکل مرتبط با <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> کار نمیکند"</string>
- <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"برای برطرف کردن مشکل، ضربه بزنید"</string>
+ <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"برای برطرف کردن مشکل، تکضرب بزنید"</string>
<string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g> خراب است. رفع خطا را انتخاب کنید."</string>
- <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"شاید لازم باشد دستگاه را دوباره قالببندی کنید. برای خارج کردن، ضربه بزنید."</string>
+ <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"شاید لازم باشد دستگاه را دوباره قالببندی کنید. برای خارج کردن، تکضرب بزنید."</string>
<string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"<xliff:g id="NAME">%s</xliff:g> تشخیص داده شد"</string>
<string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> کار نمیکند"</string>
- <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"برای راهاندازی ضربه بزنید."</string>
+ <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"برای راهاندازی تکضرب بزنید."</string>
<string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"برای راهاندازی <xliff:g id="NAME">%s</xliff:g> در قالب پشتیبانیشده، انتخاب کنید."</string>
<string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"شاید لازم باشد دستگاه را دوباره قالببندی کنید"</string>
<string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> بهطور غیرمنتظره جدا شد"</string>
@@ -1500,7 +1506,7 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"به یک برنامه اجازه میدهد جهت نادیده گرفتن بهینهسازی باتری برای خود مجوز درخواست کند."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"پُرسمان همه بستهها"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"به برنامه اجازه میدهد همه بستههای نصبشده را ببیند."</string>
- <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"برای کنترل بزرگنمایی، دو بار ضربه بزنید"</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"برای کنترل بزرگنمایی، دو بار تکضرب بزنید"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"افزودن ابزارک انجام نشد."</string>
<string name="ime_action_go" msgid="5536744546326495436">"برو"</string>
<string name="ime_action_search" msgid="4501435960587287668">"جستجو"</string>
@@ -1532,8 +1538,8 @@
<string name="notification_ranker_binding_label" msgid="432708245635563763">"سرویس ردهبندی اعلان"</string>
<string name="vpn_title" msgid="5906991595291514182">"VPN فعال شد"</string>
<string name="vpn_title_long" msgid="6834144390504619998">"VPN را <xliff:g id="APP">%s</xliff:g> فعال کرده است"</string>
- <string name="vpn_text" msgid="2275388920267251078">"برای مدیریت شبکه ضربه بزنید."</string>
- <string name="vpn_text_long" msgid="278540576806169831">"به <xliff:g id="SESSION">%s</xliff:g> متصل شد. برای مدیریت شبکه ضربه بزنید."</string>
+ <string name="vpn_text" msgid="2275388920267251078">"برای مدیریت شبکه تکضرب بزنید."</string>
+ <string name="vpn_text_long" msgid="278540576806169831">"به <xliff:g id="SESSION">%s</xliff:g> متصل شد. برای مدیریت شبکه تکضرب بزنید."</string>
<string name="vpn_lockdown_connecting" msgid="6096725311950342607">"درحال اتصال به VPN همیشه روشن…"</string>
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"VPN همیشه روشن متصل شد"</string>
<string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"از «VPN همیشه روشن» قطع شد"</string>
@@ -1544,7 +1550,7 @@
<string name="reset" msgid="3865826612628171429">"بازنشانی"</string>
<string name="submit" msgid="862795280643405865">"ارسال"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"برنامه رانندگی درحال اجرا است"</string>
- <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"برای خروج از برنامه رانندگی ضربه بزنید."</string>
+ <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"برای خروج از برنامه رانندگی تکضرب بزنید."</string>
<string name="back_button_label" msgid="4078224038025043387">"برگشت"</string>
<string name="next_button_label" msgid="6040209156399907780">"بعدی"</string>
<string name="skip_button_label" msgid="3566599811326688389">"رد شدن"</string>
@@ -1623,7 +1629,7 @@
<string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"بیشاز حدمجاز داده Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"مصرف داده شما <xliff:g id="SIZE">%s</xliff:g> از حداکثر مجاز بیشتر شده است"</string>
<string name="data_usage_restricted_title" msgid="126711424380051268">"داده پسزمینه محدود شد"</string>
- <string name="data_usage_restricted_body" msgid="5338694433686077733">"برای برداشتن محدودیت ضربه بزنید."</string>
+ <string name="data_usage_restricted_body" msgid="5338694433686077733">"برای برداشتن محدودیت تکضرب بزنید."</string>
<string name="data_usage_rapid_title" msgid="2950192123248740375">"مصرف بالای داده تلفن همراه"</string>
<string name="data_usage_rapid_body" msgid="3886676853263693432">"برنامههای شما بیش از معمول داده مصرف کردهاند"</string>
<string name="data_usage_rapid_app_body" msgid="5425779218506513861">"<xliff:g id="APP">%s</xliff:g> بیش از معمول داده مصرف کرده است"</string>
@@ -1739,7 +1745,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مجاز نبودن"</string>
<string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"حذف نصب"</string>
<string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"پاسخ شما تأیید نشد زیرا یک برنامه درخواست اجازه را مسدود کرده است."</string>
- <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"برای استفاده از ویژگی، روی آن ضربه بزنید:"</string>
+ <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"برای استفاده از ویژگی، روی آن تکضرب بزنید:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"انتخاب ویژگیهای موردنظر برای استفاده با دکمه دسترسپذیری"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"انتخاب ویژگیهای موردنظر برای استفاده با میانبر کلید میزان صدا"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> خاموش شده است"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"کلیدهای میزان صدا را رها کنید. برای روشن کردن <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید میزان صدا را مجدداً بهمدت ۳ ثانیه فشار دهید و نگه دارید."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ویژگی را انتخاب کنید که هنگام ضربه زدن روی دکمه دسترسپذیری استفاده میشود:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ویژگی را برای استفاده با اشاره دسترسپذیری انتخاب کنید (با دو انگشت صفحه را از پایین تند بهبالا بکشید):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ویزگی را برای استفاده با اشاره دسترسپذیری انتخاب کنید (با سه انگشت صفحه را از پایین تند بهبالا بکشید):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"برای جابهجایی بین ویژگیها، دکمه دسترسپذیری را لمس کنید و نگه دارید."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"برای جابهجایی بین ویژگیها، با دو انگشت صفحه را تند بهبالا بکشید و نگه دارید."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"برای جابهجایی بین ویژگیها، با سه انگشت صفحه را تند بهبالا بکشید و نگه دارید."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"درشتنمایی"</string>
<string name="user_switched" msgid="7249833311585228097">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1871,7 +1883,7 @@
<string name="reason_unknown" msgid="5599739807581133337">"نامعلوم"</string>
<string name="reason_service_unavailable" msgid="5288405248063804713">"سرویس چاپ فعال نشده است"</string>
<string name="print_service_installed_title" msgid="6134880817336942482">"سرویس <xliff:g id="NAME">%s</xliff:g> نصب شد"</string>
- <string name="print_service_installed_message" msgid="7005672469916968131">"برای فعال کردن ضربه بزنید"</string>
+ <string name="print_service_installed_message" msgid="7005672469916968131">"برای فعال کردن تکضرب بزنید"</string>
<string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"پین سرپرست سیستم را وارد کنید"</string>
<string name="restr_pin_enter_pin" msgid="373139384161304555">"پین را وارد کنید"</string>
<string name="restr_pin_incorrect" msgid="3861383632940852496">"نادرست"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"تماس درحال انجام"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"درحال غربال کردن تماس ورودی"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"دستهبندینشده"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"تبلیغات ویژه"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"اجتماعی"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"اخبار"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"توصیهها"</string>
<string name="importance_from_user" msgid="2782756722448800447">"شما اهمیت این اعلانها را تنظیم میکنید."</string>
<string name="importance_from_person" msgid="4235804979664465383">"به دلیل افراد درگیر مهم است."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"اعلان برنامه سفارشی"</string>
@@ -2032,9 +2048,9 @@
<string name="new_sms_notification_content" msgid="3197949934153460639">"برای مشاهده، برنامه پیامک را باز کنید"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"برخی از عملکردها ممکن است محدود باشند"</string>
<string name="profile_encrypted_detail" msgid="5279730442756849055">"نمایه کاری قفل است"</string>
- <string name="profile_encrypted_message" msgid="1128512616293157802">"برای باز کردن قفل ضربه بزنید"</string>
+ <string name="profile_encrypted_message" msgid="1128512616293157802">"برای باز کردن قفل تکضرب بزنید"</string>
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"به <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> متصل شد"</string>
- <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"برای دیدن فایلها، ضربه بزنید"</string>
+ <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"برای دیدن فایلها، تکضرب بزنید"</string>
<string name="pin_target" msgid="8036028973110156895">"سنجاق کردن"</string>
<string name="pin_specific_target" msgid="7824671240625957415">"سنجاق کردن <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="unpin_target" msgid="3963318576590204447">"برداشتن سنجاق"</string>
@@ -2122,11 +2138,11 @@
<string name="notification_channel_system_changes" msgid="2462010596920209678">"تغییرات سیستم"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"مزاحم نشوید"</string>
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"جدید: «مزاحم نشوید» اعلانها را پنهان میکند"</string>
- <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"برای اطلاعات بیشتر و تغییر دادن، ضربه بزنید."</string>
+ <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"برای اطلاعات بیشتر و تغییر دادن، تکضرب بزنید."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"«مزاحم نشوید» تغییر کرده است"</string>
- <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"برای بررسی موارد مسدودشده ضربه بزنید."</string>
+ <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"برای بررسی موارد مسدودشده تکضرب بزنید."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"مرور تنظیمات اعلان"</string>
- <string name="review_notification_settings_text" msgid="5916244866751849279">"از Android نسخه ۱۳ به بعد، برنامههایی که نصب میکنید برای ارسال اعلان به اجازه شما نیاز دارند. برای تغییر دادن این اجازه در برنامههای موجود، ضربه بزنید."</string>
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"از Android نسخه ۱۳ به بعد، برنامههایی که نصب میکنید برای ارسال اعلان به اجازه شما نیاز دارند. برای تغییر دادن این اجازه در برنامههای موجود، تکضرب بزنید."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"بعداً یادآوری شود"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"رد شدن"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"سیستم"</string>
@@ -2135,10 +2151,10 @@
<string name="notification_appops_microphone_active" msgid="581333393214739332">"میکروفون"</string>
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"نمایش روی برنامههای دیگر در صفحهنمایش"</string>
<string name="notification_feedback_indicator" msgid="663476517711323016">"ارائه بازخورد"</string>
- <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"این اعلان به «پیشفرض» ارتقا داده شد. برای ارائه بازخورد، ضربه بزنید."</string>
- <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"این اعلان به «بیصدا» تنزل داده شد. برای ارائه بازخورد، ضربه بزنید."</string>
- <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"این اعلان در رتبه بالاتری قرار گرفت. برای ارائه بازخورد، ضربه بزنید."</string>
- <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"این اعلان در رتبه پایینتری قرار گرفت. برای ارائه بازخورد، ضربه بزنید."</string>
+ <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"این اعلان به «پیشفرض» ارتقا داده شد. برای ارائه بازخورد، تکضرب بزنید."</string>
+ <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"این اعلان به «بیصدا» تنزل داده شد. برای ارائه بازخورد، تکضرب بزنید."</string>
+ <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"این اعلان در رتبه بالاتری قرار گرفت. برای ارائه بازخورد، تکضرب بزنید."</string>
+ <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"این اعلان در رتبه پایینتری قرار گرفت. برای ارائه بازخورد، تکضرب بزنید."</string>
<string name="nas_upgrade_notification_title" msgid="8436359459300146555">"اعلانهای بهبودیافته"</string>
<string name="nas_upgrade_notification_content" msgid="5157550369837103337">"اکنون پاسخها و کنشهای پیشنهادی ازطریق اعلانهای بهبودیافته ارائه میشوند. «اعلانهای تطبیقی Android» دیگر پشتیبانی نمیشوند."</string>
<string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"تأیید"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"انتخابگر میانبر دسترسپذیری روی صفحه"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"میانبر دسترسیپذیری"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"رد کردن کشوی اعلانات"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"منو"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"پخش/موقتاً متوقف کردن رسانه"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"پد کنترل بالا"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"پد کنترل پایین"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"پد کنترل چپ"</string>
@@ -2353,14 +2371,14 @@
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"نماد برنامه"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"تصویر نمانامسازی برنامه"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"بررسی تنظیمات دسترسی"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> میتواند صفحهنمایش شما را مشاهده و کنترل کند. برای مرور، ضربه بزنید."</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> میتواند صفحهنمایش شما را مشاهده و کنترل کند. برای مرور، تکضرب بزنید."</string>
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ترجمه شد."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیام از <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> به <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ترجمه شد."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"فعالیت در پسزمینه"</string>
<string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"برنامهای شارژ باتری را خالی میکند"</string>
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"یکی از برنامهها همچنان فعال است"</string>
- <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> در پسزمینه درحال اجرا است. برای مدیریت مصرف باتری ضربه بزنید."</string>
- <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ممکن است بر عمر باتری تأثیر بگذارد. برای مرور برنامههای فعال، ضربه بزنید."</string>
+ <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> در پسزمینه درحال اجرا است. برای مدیریت مصرف باتری تکضرب بزنید."</string>
+ <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ممکن است بر عمر باتری تأثیر بگذارد. برای مرور برنامههای فعال، تکضرب بزنید."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"بررسی برنامههای فعال"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"از <xliff:g id="DEVICE">%1$s</xliff:g> به دوربین تلفن دسترسی ندارید"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"نمیتوان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین رایانه لوحی دسترسی داشت"</string>
@@ -2391,12 +2409,12 @@
<string name="device_state_notification_settings_button" msgid="691937505741872749">"رفتن به تنظیمات"</string>
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"خاموش کردن"</string>
<string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> پیکربندی شد"</string>
- <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"جانمایی صفحهکلید روی <xliff:g id="LAYOUT_1">%s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
- <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"جانمایی صفحهکلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
- <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"جانمایی صفحهکلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
- <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"جانمایی صفحهکلید چنین تنظیم شد: <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g>… برای تغییر ضربه بزنید"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"جانمایی صفحهکلید روی <xliff:g id="LAYOUT_1">%s</xliff:g> تنظیم شد. برای تغییر دادن، تکضرب بزنید."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"جانمایی صفحهکلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> تنظیم شد. برای تغییر دادن، تکضرب بزنید."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"جانمایی صفحهکلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> تنظیم شد. برای تغییر دادن، تکضرب بزنید."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"جانمایی صفحهکلید چنین تنظیم شد: <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g>… برای تغییر تکضرب بزنید"</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"صفحهکلیدهای فیزیکی پیکربندی شدند"</string>
- <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"برای مشاهده صفحهکلیدها ضربه بزنید"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"برای مشاهده صفحهکلیدها تکضرب بزنید"</string>
<string name="profile_label_private" msgid="6463418670715290696">"خصوصی"</string>
<string name="profile_label_clone" msgid="769106052210954285">"همسانهسازی"</string>
<string name="profile_label_work" msgid="3495359133038584618">"کار"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"فضای خصوصی"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"محتوای اعلان حساس پنهان شده است"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"بهدلایل امنیتی، محتوای برنامه از دید همرسانی صفحهنمایش پنهان شد"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"بهدلایل امنیتی، محتوای برنامه پساز همرسانی صفحهنمایش پنهان میشود"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"بهطور خودکار به ماهواره متصل شد"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"میتوانید بدون شبکه تلفن همراه یا Wi-Fi پیام ارسال و دریافت کنید"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیامها»"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"روش کار"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"درحال تعلیق…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"راهاندازی مجدد «قفلگشایی با اثر انگشت»"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> خوب کار نمیکرد و حذف شد"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> خوب کار نمیکردند و حذف شدند"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> خوب کار نمیکرد و حذف شد. برای باز کردن قفل تلفن با اثر انگشت، آن را دوباره راهاندازی کنید."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> خوب کار نمیکرد و حذف شد. برای باز کردن قفل تلفن با اثر انگشت، آنها را دوباره راهاندازی کنید."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"راهاندازی مجدد «قفلگشایی با چهره»"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"مدل چهره شما خوب کار نمیکرد و حذف شد. برای باز کردن قفل تلفن با چهره، دوباره آن را راهاندازی کنید."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"راهاندازی"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"حالا نه"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"زنگ ساعت <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تغییر کاربر"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"بیصدا کردن"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"برای بیصدا کردن تکضرب بزنید"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 9a7bfff..e881a4c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Virheraportti"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Lopeta käyttökerta"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Kuvakaappaus"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Virheraportti"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Toiminto kerää tietoja laitteen tilasta ja lähettää ne sähköpostitse. Virheraportti on valmis lähetettäväksi hetken kuluttua - kiitos kärsivällisyydestäsi."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiivinen"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Poista langaton virheenkorjaus käytöstä valitsemalla tämä."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testikehystila käytössä"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Palauta tehdasasetukset, niin voit poistaa testikehystilan käytöstä."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Sarjakonsoli käytössä"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Tämä vaikuttaa suorituskykyyn. Jos haluat poistaa toiminnon käytöstä, tarkista käynnistysohjelma."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kokeellinen MTE käytössä"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vapauta äänenvoimakkuuspainikkeet. Laita <xliff:g id="SERVICE_NAME">%1$s</xliff:g> päälle painamalla äänenvoimakkuuspainikkeita uudelleen kolmen sekunnin ajan."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Valitse ominaisuus, jonka esteettömyyspainike aktivoi:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Valitse ominaisuus, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kahdella sormella):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Valitse ominaisuus, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kolmella sormella):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Vaihda ominaisuuksien välillä painamalla esteettömyyspainiketta pitkään."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Vaihda ominaisuuksien välillä pyyhkäisemällä ylös kahdella sormella ja koskettamalla pitkään."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Vaihda ominaisuuksien välillä pyyhkäisemällä ylös kolmella sormella ja koskettamalla pitkään."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurennus"</string>
<string name="user_switched" msgid="7249833311585228097">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Vaihdetaan käyttäjään <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käynnissä oleva puhelu"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Seulotaan saapuvaa puhelua"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Luokittelematon"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Tarjoukset"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Some"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Uutiset"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Suositukset"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Voit valita näiden ilmoitusten tärkeyden."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Tämä on tärkeää siihen liittyvien ihmisten perusteella."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Oma sovellusilmoitus"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Näytöllä näkyvän esteettömyyspainikkeen valitsin"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Saavutettavuuspainike"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Sulje ilmoitusalue"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Valikko"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media: toista/keskeytä"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Suuntanäppäimistö: ylös-painike"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Suuntanäppäimisto: alas-painike"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Suuntanäppäimistö: vasen painike"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Näin se toimii"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ota sormenjälkiavaus uudelleen käyttöön"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei toiminut kunnolla, ja se poistettiin"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät toimineet kunnolla, ja ne poistettiin"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei toiminut kunnolla, ja se poistettiin. Ota se uudelleen käyttöön, jotta voit avata puhelimen lukituksen sormenjäljellä."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät toimineet kunnolla, ja ne poistettiin. Ota ne uudelleen käyttöön, jotta voit avata puhelimen lukituksen sormenjäljellä."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ota kasvojentunnistusavaus uudelleen käyttöön"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Kasvomallisi ei toiminut kunnolla, ja se poistettiin. Ota se uudelleen käyttöön, jotta voit avata puhelimen lukituksen kasvoilla."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ota käyttöön"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ei nyt"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Hälytys: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Vaihda käyttäjää"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mykistä"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Mykistä äänet napauttamalla"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index cc56526..f5fc603 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Rapport de bogue"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Fermer la session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Capture d\'écran"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Rapport de bogue"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme de courriel. Merci de patienter pendant la préparation du rapport de bogue. Cette opération peut prendre quelques instants."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Rapport interactif"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Sélectionnez cette option pour désactiver le débogage sans fil."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Logiciel de test activé"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Effectuez une réinitialisation pour désactiver le mode Logiciel de test."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"La console série est activée"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"La performance est réduite. Pour désactiver cette fonction, vérifier le programme d\'amorçage."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Extension MTE expérimentale activée"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les touches de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, maintenez les deux touches de volume enfoncées pendant 3 secondes."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choisissez une fonctionnalité à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choisissez une fonctionnalité à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec deux doigts) :"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choisissez une fonctionnalité à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Pour basculer entre les fonctionnalités, maintenez le doigt sur le bouton d\'accessibilité."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Pour basculer entre les fonctionnalités, balayez l\'écran vers le haut avec deux doigts et maintenez-les-y."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pour basculer entre les fonctionnalités, balayez l\'écran vers le haut avec trois doigts et maintenez-les-y."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
<string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrer un appel entrant"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Médias sociaux"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Actualités"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommandations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vous définissez l\'importance de ces notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ces notifications sont importantes en raison des participants."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'application personnalisée"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Sélecteur de raccourci d\'accessibilité à l\'écran"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorer le volet de notification"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Lecture/pause du contenu multimédia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pavé directionnel – haut"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pavé directionnel – bas"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pavé directionnel – gauche"</string>
@@ -2412,19 +2430,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espace privé"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Le contenu confidentiel de la notification est masqué"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'application est masqué du Partage d\'écran par mesure de sécurité"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué du Partage d\'écran par mesure de sécurité"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Connecté au satellite automatiquement"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans avoir recours à un appareil mobile ou à un réseau Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurer le Déverrouillage par empreinte digitale à nouveau"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas bien et a été supprimée"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas bien et ont été supprimées"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas bien et a été supprimée. Configurez-le à nouveau pour déverrouiller votre téléphone avec l\'empreinte digitale."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas bien et ont été supprimées. Configurez-les à nouveau pour déverrouiller votre téléphone avec votre empreinte digitale."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configurer le Déverrouillage par reconnaissance faciale à nouveau"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Votre modèle facial ne fonctionnait pas bien et a été supprimé. Configurez-le à nouveau pour déverrouiller votre téléphone avec votre visage."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurer"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Plus tard"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme pour <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Changer d\'utilisateur"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Désactiver le son"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toucher pour désactiver le son"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f1a81a3..4bcf9a6 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Rapport de bug"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Fermer la session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Capture d\'écran"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Signaler un bug"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme d\'e-mail. Merci de patienter pendant la préparation du rapport de bug. Cette opération peut prendre quelques instants."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Rapport interactif"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Sélectionnez cette option pour désactiver le débogage sans fil."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Atelier de test activé"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Console série activée"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Les performances sont affectées. Pour désactiver la console série, vérifiez le bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE expérimentale activée"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les boutons de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, appuyez de nouveau sur les deux boutons de volume pendant trois secondes."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choisissez une fonctionnalité à utiliser lorsque vous appuyez sur le bouton Accessibilité :"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choisissez une fonctionnalité à utiliser avec le geste d\'accessibilité (balayez l\'écran de bas en haut avec deux doigts) :"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choisissez une fonctionnalité à utiliser avec le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Pour changer de fonctionnalité, appuyez de manière prolongée sur le bouton Accessibilité."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Pour changer de fonctionnement, balayez l\'écran vers le haut avec deux doigts et appuyez de manière prolongée."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pour changer de fonctionnalité, balayez l\'écran vers le haut avec trois doigts et appuyez de manière prolongée."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
<string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passage à <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrage d\'un appel entrant"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Réseaux sociaux"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Actualités"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommandations"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vous définissez l\'importance de ces notifications."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ces notifications sont importantes en raison des participants."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'application personnalisée"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Outil de sélection des raccourcis d\'accessibilité à l\'écran"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Fermer le volet des notifications"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Contenu multimédia : lecture/pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pavé directionnel - Haut"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pavé directionnel - Bas"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pavé directionnel - Gauche"</string>
@@ -2412,19 +2430,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espace privé"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Le contenu sensible de la notification a été masqué"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran pour des raisons de sécurité"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran par mesure de sécurité"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Connecté automatiquement au réseau satellite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans connexion au réseau mobile ou Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Reconfigurer le déverrouillage par empreinte digitale"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas correctement et a été supprimée"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas correctement et ont été supprimées"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas correctement et a été supprimée. Configurez-la à nouveau pour déverrouiller votre téléphone à l\'aide de votre empreinte digitale."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas correctement et ont été supprimées. Configurez-les à nouveau pour déverrouiller votre téléphone à l\'aide de votre empreinte digitale."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Reconfigurer le déverrouillage par reconnaissance faciale"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Votre empreinte faciale ne fonctionnait pas correctement et a été supprimée. Configurez-la à nouveau pour déverrouiller votre téléphone à l\'aide de votre visage."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuration"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Pas maintenant"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme pour <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Changer d\'utilisateur"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Couper le son"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Appuyer pour couper le son"</string>
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index c29d888..6bfebb4 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Informe de erros"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Finalizar a sesión"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Capt. pantalla"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Informe de erros"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Este informe recompilará información acerca do estado actual do teu dispositivo para enviala en forma de mensaxe de correo electrónico. O informe de erros tardará un pouco en completarse desde o seu inicio ata que estea preparado para enviarse, polo que che recomendamos que teñas paciencia."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Informe interactivo"</string>
@@ -642,7 +644,7 @@
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a aplicación lea as localizacións da túa colección multimedia."</string>
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilizar desbloqueo biométrico"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar desbloqueo biométrico ou credencial do dispositivo"</string>
- <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que es ti"</string>
+ <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica a túa identidade"</string>
<string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Para continuar, utiliza o desbloqueo biométrico"</string>
<string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Para continuar, utiliza o desbloqueo biométrico ou o bloqueo de pantalla"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"O hardware biométrico non está dispoñible"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona para desactivar a depuración sen fíos."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Activouse o modo de axente de proba"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece a configuración de fábrica para desactivar o modo de axente de proba."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"A consola de serie está activada"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"O rendemento vese afectado. Para desactivar a consola, comproba o cargador de arranque."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"A MTE experimental está activada"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solta as teclas de volume. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantenas premidas de novo durante 3 segundos."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolle a función que queres utilizar cando toques o botón Accesibilidade:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolle a función que queres usar co xesto de accesibilidade (pasa dous dedos cara arriba desde a parte inferior da pantalla):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolle a función que queres usar co xesto de accesibilidade (pasa tres dedos cara arriba desde a parte inferior da pantalla):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para cambiar de función, mantén premido o botón Accesibilidade."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para cambiar de función, pasa dous dedos cara arriba pola pantalla e mantén premido."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para cambiar de función, pasa tres dedos cara arriba pola pantalla e mantén premido."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada en curso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando chamada entrante"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sen clasificar"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocións"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Novidades"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendacións"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ti defines a importancia destas notificacións."</string>
<string name="importance_from_person" msgid="4235804979664465383">"É importante polas persoas involucradas."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de aplicación personalizada"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de atallos de accesibilidade en pantalla"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atallo de accesibilidade"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorar panel despregable"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproducir/pór en pausa contido multimedia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Cruceta: arriba"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Cruceta: abaixo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Cruceta: esquerda"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espazo privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Contido confidencial da notificación oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por motivos de seguranza, ocultouse o contido da aplicación para que no se mostre na pantalla compartida"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por seguranza, ocultouse o contido da aplicación na pantalla compartida"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática ao satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Podes enviar e recibir mensaxes sen unha rede de telefonía móbil ou wifi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura de novo o desbloqueo dactilar"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A <xliff:g id="FINGERPRINT">%s</xliff:g> non funcionaba correctamente, polo que se eliminou"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impresións dixitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funcionaban correctamente, polo que se eliminaron"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A <xliff:g id="FINGERPRINT">%s</xliff:g> non funcionaba correctamente, polo que se eliminou. Configúraa de novo para desbloquear o teléfono usando a impresión dixital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impresións dixitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funcionaban correctamente, polo que se eliminaron. Configúraas de novo para desbloquear o teléfono usando a impresión dixital."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configura de novo o desbloqueo facial"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"O teu modelo facial non funcionaba correctamente, polo que se eliminou. Configúrao de novo para desbloquear o teléfono usando a cara."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora non"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tocar para silenciar o son"</string>
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 8fe9a5b..fd2134a 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"બગ રિપોર્ટ"</string>
<string name="global_action_logout" msgid="6093581310002476511">"સત્ર સમાપ્ત કરો"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"સ્ક્રીનશૉટ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"બગ રિપોર્ટ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"આ, એક ઇ-મેઇલ સંદેશ તરીકે મોકલવા માટે, તમારા વર્તમાન ઉપકરણ સ્થિતિ વિશેની માહિતી એકત્રિત કરશે. એક બગ રિપોર્ટ પ્રારંભ કરીને તે મોકલવા માટે તૈયાર ન થઈ જાય ત્યાં સુધી તેમાં થોડો સમય લાગશે; કૃપા કરીને ધીરજ રાખો."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ક્રિયાપ્રતિક્રિયાત્મક રિપોર્ટ"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"વાયરલેસ ડિબગીંગ બંધ કરવા માટે પસંદ કરો."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ટેસ્ટ હાર્નેસ મોડ ચાલુ કર્યો"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ટેસ્ટ હાર્નેસ મોડ બંધ કરવા માટે ફૅક્ટરી રીસેટ કરો."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"સિરીયલ કન્સોલ ચાલુ થયો"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"કાર્યપ્રદર્શનને અસર થાય છે. બંધ કરવા માટે, બૂટલોડર ચેક કરો."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"પ્રયોગાત્મક MTE ચાલુ કર્યું"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"વૉલ્યૂમ કી છોડી દો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ને ચાલુ કરવા માટે, 3 સેકન્ડ માટે બન્ને વૉલ્યૂમ કીને ફરીથી દબાવી રાખો."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સુવિધા પસંદ કરો:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સુવિધા પસંદ કરો (બે આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સુવિધા પસંદ કરો (ત્રણ આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, ઍક્સેસિબિલિટી બટનને ટચ કરીને થોડીવાર દબાવી રાખો."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, બે આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, ત્રણ આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"મોટું કરવું"</string>
<string name="user_switched" msgid="7249833311585228097">"વર્તમાન વપરાશકર્તા <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છે…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"ચાલુ કૉલ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ઇનકમિંગ કૉલનું સ્ક્રીનિંગ થાય છે"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"અવર્ગીકૃત"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"પ્રમોશન"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"સામાજિક"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ન્યૂઝ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"સુઝાવો"</string>
<string name="importance_from_user" msgid="2782756722448800447">"તમે આ સૂચનાઓનું મહત્વ સેટ કર્યું છે."</string>
<string name="importance_from_person" msgid="4235804979664465383">"શામેલ થયેલ લોકોને કારણે આ મહત્વપૂર્ણ છે."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ઍપનું કસ્ટમ નોટિફિકેશન"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"સ્ક્રીન પરના ઍક્સેસિબિલિટી શૉર્ટકટના પસંદકર્તા"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ઍક્સેસિબિલિટી શૉર્ટકટ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"નોટિફિકેશન શેડ છોડી દો"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"મેનૂ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"મીડિયા ચલાવો/થોભાવો"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ડી-પૅડ ઉપર"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ડી-પૅડ નીચે"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ડી-પૅડ ડાબે"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"તેની કામ કરવાની રીત"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"બાકી..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> યોગ્ય રીતે કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> યોગ્ય રીતે કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> બરાબર કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી. તમારા ફોનને ફિંગરપ્રિન્ટ વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> બરાબર કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી. તમારા ફોનને તમારી ફિંગરપ્રિન્ટ વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ફેસ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"તમારા ચહેરાનું મૉડલ બરાબર કામ કરતું ન હતું અને તેને ડિલીટ કરવામાં આવ્યું હતું. તમારા ફોનને ચહેરા વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"સેટઅપ કરો"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"હમણાં નહીં"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> માટે અલાર્મ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"વપરાશકર્તા સ્વિચ કરો"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"મ્યૂટ કરો"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"સાઉન્ડ મ્યૂટ કરવા માટે ટૅપ કરો"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 39e6625..84df116 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"गड़बड़ी की रिपोर्ट"</string>
<string name="global_action_logout" msgid="6093581310002476511">"सत्र खत्म करें"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"स्क्रीनशॉट"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"गड़बड़ी की रिपोर्ट"</string>
<string name="bugreport_message" msgid="5212529146119624326">"इससे ईमेल भेजने के लिए, आपके डिवाइस की मौजूदा स्थिति से जुड़ी जानकारी इकट्ठा की जाएगी. गड़बड़ी की रिपोर्ट बनना शुरू होने से लेकर भेजने के लिए तैयार होने तक कुछ समय लगेगा; कृपया इंतज़ार करें."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"सहभागी रिपोर्ट"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वॉयरलेस डीबगिंग की सुविधा बंद करने के लिए चुनें."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"टेस्ट हार्नेस मोड चालू किया गया"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"टेस्ट हार्नेस मोड बंद करने के लिए फ़ैक्ट्री रीसेट करें."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"सीरियल कंसोल को चालू करें"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"परफ़ॉर्मेंस पर असर पड़ा है. बंद करने के लिए बूटलोडर चुनें."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"आज़माने के लिए एमटीई चालू है"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"आवाज़ बटन को छोड़ें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> की सुविधा चालू करने के लिए, आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"सुलभता बटन पर टैप करके, इस्तेमाल करने के लिए सुविधा चुनें:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"सुलभता वाले हाथ के जेस्चर (हाव-भाव) के साथ इस्तेमाल करने के लिए सुविधा चुनें (दो उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"सुलभता वाले हाथ के जेस्चर (हाव-भाव) के साथ इस्तेमाल करने के लिए सुविधा चुनें (तीन उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, सुलभता बटन दबाकर रखें."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, स्क्रीन पर दो उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक उंगलियां स्क्रीन पर रखे रहें."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, स्क्रीन पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक उंगलियां स्क्रीन पर रखे रहें."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"अगली बार सुलभता बटन पर टैप करने से, यह सुविधा चालू हो जाएगी"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर दो उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर तीन उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ज़ूम करने की सुविधा"</string>
<string name="user_switched" msgid="7249833311585228097">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"पहले से जारी कॉल"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल को स्क्रीन किया जा रहा है"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"बिना किसी श्रेणी के"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"प्रमोशन"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"सोशल"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"खबरें"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"सुझाव"</string>
<string name="importance_from_user" msgid="2782756722448800447">"आपने इन सूचनाओं की अहमियत सेट की है."</string>
<string name="importance_from_person" msgid="4235804979664465383">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ऐप्लिकेशन की सूचना पसंद के मुताबिक बनाएं"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"स्क्रीन पर दिखने वाले सुलभता के शॉर्टकट को चुनने का मेन्यू"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"सुलभता का शॉर्टकट"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"नोटिफ़िकेशन शेड खारिज करें"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"मेन्यू"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"मीडिया चलाएं/रोकें"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"डी-पैड का ऊपर वाला बटन"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"डी-पैड का नीचे वाला बटन"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"डी-पैड का बाईं ओर वाला बटन"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यह सेटिंग कैसे काम करती है"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रोसेस जारी है..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"अच्छे से काम न करने की वजह से <xliff:g id="FINGERPRINT">%s</xliff:g> को मिटा दिया गया"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"अच्छे से काम न करने की वजह से, <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> को मिटा दिया गया"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"अच्छे से काम न करने की वजह से <xliff:g id="FINGERPRINT">%s</xliff:g> को मिटा दिया गया. फ़िंगरप्रिंट की मदद से फ़ोन अनलॉक करने के लिए, फ़िंगरप्रिंट अनलॉक की सुविधा को दोबारा सेट अप करें."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"अच्छे से काम न करने की वजह से, <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> को मिटा दिया गया. फ़िंगरप्रिंट की मदद से फ़ोन अनलॉक करने के लिए, फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"फ़ेस अनलॉक की सुविधा को दोबारा सेट अप करें"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"अच्छे से काम न करने की वजह से, चेहरे का मॉडल मिटा दिया गया. फ़ेस अनलॉक की सुविधा की मदद से फ़ोन अनलॉक करने के लिए, इस सुविधा को दोबारा सेट अप करें."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट अप करें"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अभी नहीं"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> के लिए अलार्म"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"दूसरे खाते पर स्विच करें"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्यूट करें"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"आवाज़ म्यूट करने के लिए टैप करें"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 08ea4a2..ace3727 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Izvješće o programskim pogreškama"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snimka zaslona"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Izvješće o programskim pogreškama"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Time će se prikupiti podaci o trenutačnom stanju vašeg uređaja koje ćete nam poslati u e-poruci. Za pripremu izvješća o programskoj pogrešci potrebno je nešto vremena pa vas molimo za strpljenje."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktivno izvješće"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Odaberite da biste onemogućili bežično otklanjanje pogrešaka."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je način testnog okvira"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Vratite na tvorničke postavke da biste onemogućili način testnog okvira."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola omogućena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Izvedba je otežana. Provjerite pokretač operativnog sustava da biste onemogućili konzolu."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Omogućen je eksperimentalni MTE"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za glasnoću. Da biste uključili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za glasnoću tri sekunde."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Odaberite značajku koju ćete upotrebljavati kada dodirnete gumb za Pristupačnost:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite za koju će se značajku upotrebljavati pokret pristupačnosti (prelazak s dva prsta prema gore od dna zaslona):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite za koju će se značajku upotrebljavati pokret pristupačnosti (prelazak s tri prsta prema gore od dna zaslona):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Da biste prešli na neku drugu značajku, dodirnite i zadržite gumb za Pristupačnost."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da biste prešli na neku drugu značajku, prijeđite s dva prsta prema gore i zadržite."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da biste prešli na neku drugu značajku, prijeđite s tri prsta prema gore i zadržite."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povećavanje"</string>
<string name="user_switched" msgid="7249833311585228097">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u tijeku"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nema kategorije"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Društvene mreže"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Vijesti"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Preporuke"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Postavili ste važnost tih obavijesti."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Važno je zbog uključenih osoba."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođena obavijest aplikacije"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alat za odabir prečaca pristupačnosti na zaslonu"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečac pristupačnosti"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbacivanje zaslona obavijesti"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Izbornik"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproduciraj/pauziraj medijske sadržaje"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Gore na plohi za smjerove"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dolje na plohi za smjerove"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Lijevo na plohi za smjerove"</string>
@@ -2419,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako to funkcionira"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovno postavite otključavanje otiskom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao i izbrisan je"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali i izbrisani su"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao i izbrisan je. Ponovno ga postavite da biste otključali telefon otiskom prsta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali i izbrisani su. Ponovno ih postavite da biste otključali telefon otiskom prsta."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovno postavite otključavanje licem"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model vašeg lica nije dobro funkcionirao i izbrisan je. Ponovno ga postavite da biste otključali telefon licem."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavi"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sad"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Promijeni korisnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite za isključivanje zvuka"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 729fad9..23b5fee 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Programhiba bejelentése"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Munkamenet befejezése"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Képernyőkép"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Programhiba bejelentése"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ezzel információt fog gyűjteni az eszköz jelenlegi állapotáról, amelyet a rendszer e-mailben fog elküldeni. Kérjük, legyen türelemmel, amíg a hibajelentés elkészül, és küldhető állapotba kerül."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktív jelentés"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Válassza ezt a vezeték nélküli hibakeresés letiltásához."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tesztelési alapkörnyezet mód engedélyezve"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"A Tesztelési alapkörnyezet mód kikapcsolásához állítsa vissza a gyári beállításokat."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Soros konzol engedélyezve"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ez hatással van a teljesítményre. A letiltáshoz ellenőrizze a rendszerindítót."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kísérleti MTE engedélyezve"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Engedje fel a hangerőszabályzó gombokat. A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolásához tartsa újra lenyomva a hangerőszabályzó gombokat három másodpercig."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Válassza ki a Kisegítő lehetőségek gombra koppintáskor használni kívánt funkciót:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Válassza ki a kisegítő kézmozdulattal (felfelé csúsztatás két ujjal a képernyő aljáról) használni kívánt funkciót:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Válassza ki a kisegítő kézmozdulattal (felfelé csúsztatás három ujjal a képernyő aljáról) használni kívánt funkciót:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"A funkciók közötti váltáshoz tartsa lenyomva a Kisegítő lehetőségek gombot."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"A funkciók közötti váltáshoz csúsztassa felfelé két ujját, és ne emelje fel őket a képernyőről."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"A funkciók közötti váltáshoz csúsztassa felfelé három ujját, és ne emelje fel őket a képernyőről."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Nagyítás"</string>
<string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Átváltás erre: <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Hívás folyamatban"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Bejövő hívás szűrése"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nincs kategóriába sorolva"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promóciók"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Közösségi"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Hírek"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Javaslatok"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ön állította be ezen értesítések fontossági szintjét."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ez az üzenet a résztvevők miatt fontos."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Egyéni alkalmazásértesítés"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Képernyőn megjelenő kisegítő lehetőségekre vonatkozó parancsválasztó"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kisegítő lehetőségek gyorsparancsa"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Értesítési felület bezárása"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Médialejátszás/szüneteltetés"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad – fel"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad – le"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad – balra"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privát terület"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Bizalmas értesítéstartalom elrejtve"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"A biztonság érdekében a képernyőmegosztástól elrejtett alkalmazástartalom"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Apptartalom elrejtve a megosztástól a biztonság érdekében"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automatikusan csatlakozva a műholdhoz"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hogyan működik?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Függőben…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"A Feloldás ujjlenyomattal funkció újbóli beállítása"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A(z) <xliff:g id="FINGERPRINT">%s</xliff:g> nem működött megfelelően, ezért törölve lett"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"A(z) <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és a(z) <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nem működtek megfelelően, ezért törölve lettek"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A(z) <xliff:g id="FINGERPRINT">%s</xliff:g> nem működött megfelelően, ezért törölve lett. Állítsa be újra, hogy feloldhassa a telefonját az ujjlenyomata segítségével."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"A(z) <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és a(z) <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nem működtek megfelelően, ezért törölve lettek. Állítsa be őket újra, hogy feloldhassa a telefonját az ujjlenyomata segítségével."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Állítsa be újra az Arcalapú feloldást"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Az arcmodellje nem működött megfelelően, ezért törölve lett. Állítsa be újra, hogy feloldhassa a telefonját az arca segítségével."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Beállítás"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Most nem"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Riasztás <xliff:g id="USER_NAME">%s</xliff:g> részére"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Felhasználóváltás"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Némítás"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Koppintson a hang elnémításához"</string>
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index c3eec0f..4f9d478 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Հաղորդում վրիպակի մասին"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Ավարտել աշխատաշրջանը"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Սքրինշոթ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Հաղորդում վրիպակի մասին"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Ինտերակտիվ զեկույց"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Սեղմեք՝ անլար վրիպազերծումն անջատելու համար:"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Թեստային ռեժիմը միացված է"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Սերիական վահանակը միացված է"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Աշխատանքի արդյունավետությունը նվազում է։ Վահանակն անջատելու համար ստուգեք օպերացիոն համակարգի բեռնիչը։"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Միացված է փորձնական MTE գործառույթը"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացավ։"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունն անջատվեց։"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Բաց թողեք ձայնի ուժգնության կոճակները։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացնելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակը։"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Ընտրեք գործառույթը, որը կգործարկվի «Հատուկ գործառույթներ» կոճակին հպելու դեպքում՝"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Ընտրեք գործառույթը, որը կգործարկվի հատուկ գործառույթների ժեստը (երկու մատը էկրանի ներքևից սահեցրեք վերև) անելու դեպքում՝"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Ընտրեք գործառույթը, որը կգործարկվի հատուկ գործառույթների ժեստը (երեք մատը էկրանի ներքևից սահեցրեք վերև) անելու դեպքում՝"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Մի գործառույթից մյուսին անցնելու համար հպեք «Հատուկ գործառույթներ» կոճակին և պահեք։"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Մի գործառույթից մյուսին անցնելու համար երկու մատը սահեցրեք վերև և պահեք։"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Մի գործառույթից մյուսին անցնելու համար երեք մատը սահեցրեք վերև և պահեք։"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Խոշորացում"</string>
<string name="user_switched" msgid="7249833311585228097">"Ներկայիս օգտատերը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Անցում <xliff:g id="NAME">%1$s</xliff:g> պրոֆիլին..."</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ընթացիկ զանգ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Մուտքային զանգի զտում"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Չդասակարգված"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Պրոմոակցիաներ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Սոցցանցեր"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Նորություններ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Առաջարկներ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string>
<string name="importance_from_person" msgid="4235804979664465383">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Հատուկ հավելվածի ծանուցում"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Հատուկ գործառույթների դյուրանցման ընտրիչ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Հատուկ գործառույթների դյուրանցում"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Փակել ծանուցումների վահանակը"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Ընտրացանկ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Նվագարկում/դադար"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad-ի «Վերև» կոճակ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad-ի «Ներքև» կոճակ"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad-ի «Ձախ» կոճակ"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Մասնավոր տարածք"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Ծանուցման զգայուն բովանդակությունը թաքցված է"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներից ելնելով՝ հավելվածի բովանդակությունը թաքցվել է էկրանի ցուցադրումից"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներով՝ բովանդակությունը թաքցվել է ցուցադրումից"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Ավտոմատ միացել է արբանյակին"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Դուք կարող եք ուղարկել և ստանալ հաղորդագրություններ՝ առանց բջջային կամ Wi-Fi կապի"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ինչպես է դա աշխատում"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Առկախ է…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Նորից կարգավորեք մատնահետքով ապակողպումը"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"«<xliff:g id="FINGERPRINT">%s</xliff:g>» մատնահետքը հեռացվել է, քանի որ լավ չէր աշխատում"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"«<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>» և «<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>» մատնահետքերը հեռացվել են, քանի որ լավ չէին աշխատում"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"«<xliff:g id="FINGERPRINT">%s</xliff:g>» մատնահետքը հեռացվել է, քանի որ լավ չէր աշխատում։ Նորից կարգավորեք այն՝ ձեր հեռախոսը մատնահետքով ապակողպելու համար։"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"«<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>» և «<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>» մատնահետքերը հեռացվել են, քանի որ լավ չէին աշխատում։ Նորից կարգավորեք դրանք՝ ձեր հեռախոսը մատնահետքով ապակողպելու համար։"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Նորից կարգավորեք դեմքով ապակողպումը"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ձեր դեմքի նմուշը հեռացվել է, քանի որ լավ չէր աշխատում։ Նորից կարգավորեք այն՝ ձեր հեռախոսը դեմքով ապակողպելու համար։"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Կարգավորել"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ոչ հիմա"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-ի զարթուցիչ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Անցնել մյուս հաշիվ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Անտեսել"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Հպեք՝ ձայնն անջատելու համար"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 34a52e4..2fabef3 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Laporan bug"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Akhiri sesi"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Laporan bug"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ini akan mengumpulkan informasi status perangkat Anda saat ini, untuk dikirimkan sebagai pesan email. Harap bersabar, mungkin perlu waktu untuk memulai laporan bug hingga siap dikirim."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Laporan interaktif"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pilih untuk menonaktifkan proses debug nirkabel."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Tes Otomatis diaktifkan"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Lakukan reset ke setelan pabrik untuk menonaktifkan Mode Tes Otomatis."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Konsol serial diaktifkan"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performa terpengaruh. Untuk menonaktifkan, periksa bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE eksperimental diaktifkan"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan dan tahan kedua tombol volume lagi selama 3 detik."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pilih fitur yang akan digunakan saat mengetuk tombol aksesibilitas:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pilih fitur yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan dua jari):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pilih fitur yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan tiga jari):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Sentuh lama tombol aksesibilitas untuk beralih ke fitur lain."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Geser ke atas dengan dua jari dan tahan untuk beralih ke fitur lain."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Geser ke atas dengan tiga jari dan tahan untuk beralih ke fitur lain."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string>
<string name="user_switched" msgid="7249833311585228097">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Tidak dikategorikan"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosi"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosial"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Berita"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomendasi"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Anda menyetel nilai penting notifikasi ini."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ini penting karena orang-orang yang terlibat."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notifikasi aplikasi kustom"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pemilih Pintasan Aksesibilitas di layar"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pintasan Aksesibilitas"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Tutup Menu Notifikasi"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Putar/Jeda Media"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Atas"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Bawah"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Kiri"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Ruang privasi"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Konten notifikasi sensitif disembunyikan"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar untuk alasan keamanan"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar karena alasan keamanan"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Menghubungkan otomatis ke satelit"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Anda dapat mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara kerjanya"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Tertunda..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Siapkan Buka dengan Sidik Jari lagi"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dihapus"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dihapus"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan sidik jari."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan sidik jari."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Siapkan Buka dengan Wajah lagi"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model wajah Anda tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan wajah."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Penyiapan"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Lain kali"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm untuk <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Ganti pengguna"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Bisukan"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ketuk untuk membisukan suara"</string>
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9495626..dd47ceb 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Villutilkynning"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Ljúka lotu"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Skjámynd"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Villutilkynning"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Þetta safnar upplýsingum um núverandi stöðu tækisins til að senda með tölvupósti. Það tekur smástund frá því villutilkynningin er ræst og þar til hún er tilbúin til sendingar – sýndu biðlund."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Gagnvirk skýrsla"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Veldu til að slökkva á þráðlausri villuleit."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Kveikt á stillingu prófunarvangs"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Núllstilltu til að slökkva á stillingu prófunarvangs."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Raðstjórnborð virkjað"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Þetta hefur áhrif á afköst. Athugaðu ræsiforritið ef þú vilt gera þetta óvirkt."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kveikt á MTE á tilraunarstigi"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slepptu hljóðstyrkstökkunum. Til að kveikja á <xliff:g id="SERVICE_NAME">%1$s</xliff:g> skaltu halda báðum hljóðstyrkstökkunum aftur inni í 3 sekúndur."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Veldu eiginleika sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Veldu eiginleika sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með tveimur fingrum):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Veldu eiginleika sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með þremur fingrum):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Til að skipta á milli eiginleika skaltu halda aðgengishnappinum inni."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Til að skipta á milli eiginleika skaltu strjúka upp með tveimur fingrum og halda inni."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Til að skipta á milli eiginleika skaltu strjúka upp með þremur fingrum og halda inni."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Stækkun"</string>
<string name="user_switched" msgid="7249833311585228097">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Símtal í gangi"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Síar símtal sem berst"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Óflokkað"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Kynningar"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Samfélag"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Fréttir"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tillögur"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Þú stilltir mikilvægi þessara tilkynninga."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Þetta er mikilvægt vegna fólksins sem tekur þátt í þessu."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Sérsniðin forritatilkynning"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Val um flýtileið í aðgengiseiginleika á skjánum"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Flýtileið aðgengisstillingar"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Loka tilkynningaglugga"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Valmynd"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Spila/gera hlé á margmiðlunarefni"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Upphnappur stýriflatar"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Niðurhnappur stýriflatar"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Vinstrihnappur stýriflatar"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Svona virkar þetta"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Í bið…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setja upp fingrafarskenni aftur"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkaði illa og var eytt."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkuðu illa og var eytt."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkaði illa og var eytt. Settu það upp aftur til að taka símann úr lás með fingrafari."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkuðu illa og var eytt. Settu þau upp aftur til að taka símann úr lás með fingrafarinu þínu."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Setja upp andlitskenni aftur"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Andlitslíkanið þitt virkaði illa og var eytt. Settu það upp aftur til að taka símann úr lás með andlitinu."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Setja upp"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ekki núna"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Viðvörun fyrir <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Skipta um notanda"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Þagga"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ýttu til að þagga hljóð"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3952837..94b68b0 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Segnalazione di bug"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Termina sessione"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Segnalazione di bug"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Verranno raccolte informazioni sullo stato corrente del dispositivo che saranno inviate sotto forma di messaggio email. Passerà un po\' di tempo prima che la segnalazione di bug aperta sia pronta per essere inviata; ti preghiamo di avere pazienza."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Report interattivo"</string>
@@ -420,9 +422,9 @@
<string name="permdesc_runInBackground" msgid="4344539472115495141">"Questa app può essere eseguita in background, velocizzando il consumo della batteria."</string>
<string name="permlab_useDataInBackground" msgid="783415807623038947">"utilizzo dei dati in background"</string>
<string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Questa app può usare dati in background, aumentando l\'utilizzo dei dati."</string>
- <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Pianificare la precisione delle azioni temporizzate"</string>
+ <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Programma azioni temporizzate con precisione"</string>
<string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Questa app può pianificare il lavoro al momento desiderato nel futuro. Significa anche che l\'app può essere eseguita quando non stai attivamente utilizzando il dispositivo."</string>
- <string name="permlab_use_exact_alarm" msgid="348045139777131552">"Pianifica sveglie o promemoria eventi"</string>
+ <string name="permlab_use_exact_alarm" msgid="348045139777131552">"Programma sveglie o promemoria eventi"</string>
<string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Quest\'app può pianificare azioni come sveglie e promemoria per notificarti al momento desiderato nel futuro."</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"esecuzione permanente delle applicazioni"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Consente all\'applicazione di rendere persistenti in memoria alcune sue parti. Ciò può limitare la memoria disponibile per altre applicazioni, rallentando il tablet."</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Seleziona per disattivare il debug wireless."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modalità test harness attivata"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Ripristina le impostazioni di fabbrica per disattivare la modalità test harness."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Console seriale attivata"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ci sono conseguenze sulle prestazioni. Per disattivare, seleziona il bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Funzionalità MTE sperimentale attivata"</string>
@@ -1756,12 +1762,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Rilascia i tasti del volume. Per attivare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tieni di nuovo premuti entrambi i tasti del volume per 3 secondi."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Scegli una funzionalità da usare quando tocchi il pulsante Accessibilità:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Scegli una funzionalità da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con due dita):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Scegli una funzionalità da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con tre dita):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Per spostarti tra le funzionalità, tocca e tieni premuto il pulsante Accessibilità."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Per spostarti tra le funzionalità, scorri verso l\'alto con due dita e tieni premuto."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Per spostarti tra le funzionalità, scorri verso l\'alto con tre dita e tieni premuto."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La funzionalità si aprirà la prossima volta che toccherai il pulsante Accessibilità"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 2 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 3 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ingrandimento"</string>
<string name="user_switched" msgid="7249833311585228097">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1986,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chiamata in corso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Applicazione filtro a chiamata in arrivo"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Senza categoria"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promozioni"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Novità"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Contenuti consigliati"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Stabilisci tu l\'importanza di queste notifiche."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Importante a causa delle persone coinvolte."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notifica app personalizzata"</string>
@@ -2193,6 +2206,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selettore scorciatoia Accessibilità sullo schermo"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Scorciatoia Accessibilità"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora area notifiche"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Play/Pausa contenuti multimediali"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad - Su"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad - Giù"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad - Sinistra"</string>
@@ -2419,12 +2434,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Come funziona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> non funzionava bene ed è stata eliminata"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funzionavano bene e sono state eliminate"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> non funzionava bene ed è stata eliminata. Riconfigurala per sbloccare lo smartphone con l\'impronta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funzionavano bene e sono state eliminate. Riconfigurale per sbloccare lo smartphone con l\'impronta."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Riconfigura lo Sblocco con il Volto"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Il tuo modello del volto non funzionava bene ed è stato eliminato. Riconfiguralo per sbloccare lo smartphone con il volto."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Non ora"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Sveglia per: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambia utente"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Disattiva audio"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tocca per disattivare l\'audio"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 9c143c7..f9b1d03 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"דוח איתור באגים"</string>
<string name="global_action_logout" msgid="6093581310002476511">"סיום הפעלה"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"צילום מסך"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"דיווח על באג"</string>
<string name="bugreport_message" msgid="5212529146119624326">"הפעולה הזו תאסוף מידע על מצב המכשיר הנוכחי שלך כדי לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת הדיווח על הבאג ועד לשליחת ההודעה בפועל. יש להמתין בסבלנות."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"דוח אינטראקטיבי"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"יש לבחור כדי להשבית ניפוי באגים אלחוטי."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"מצב מסגרת בדיקה הופעל"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"כדי להשבית את מצב \'מסגרת בדיקה\' צריך לאפס להגדרות היצרן."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"קונסולה סדרתית מופעלת"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"קיימת השפעה על הביצועים. כדי להשבית, יש לבדוק את תוכנת האתחול."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ה-MTE הניסיוני הופעל"</string>
@@ -1756,12 +1762,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"אפשר לשחרר את מקש עוצמת הקול. כדי להפעיל את השירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, צריך ללחוץ לחיצה ארוכה על שני המקשים של עוצמת הקול שוב במשך 3 שניות."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"צריך לבחור תכונה שתופעל כשלוחצים על לחצן הנגישות:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"יש לבחור תכונה שתופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שתי אצבעות):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"יש לבחור תכונה שתופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שלוש אצבעות):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"כדי לעבור בין תכונות, יש ללחוץ לחיצה ארוכה על לחצן הנגישות."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"כדי לעבור בין תכונות, יש להחליק כלפי מעלה בעזרת שתי אצבעות ולהחזיק."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"כדי לעבור בין תכונות, יש להחליק כלפי מעלה בעזרת שלוש אצבעות ולהחזיק."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"התכונה תיפתח בפעם הבאה שתזוהה הקשה על לחצן הנגישות"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 2 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 3 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"הגדלה"</string>
<string name="user_switched" msgid="7249833311585228097">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"מעבר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1986,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"שיחה פעילה"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"סינון שיחה נכנסת"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ללא שיוך לקטגוריה"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"קידומי מכירות"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"רשתות חברתיות"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"חדשות"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"המלצות"</string>
<string name="importance_from_user" msgid="2782756722448800447">"עליך להגדיר את החשיבות של ההתראות האלה."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ההודעה חשובה בשל האנשים המעורבים."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"התראות אפליקציה בהתאמה אישית"</string>
@@ -2193,6 +2206,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"בורר קיצורי דרך לנגישות במסך"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"קיצור דרך לנגישות"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"סגירת לוח ההתראות"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"תפריט"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"הפעלה/השהיה של המדיה"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"לחצן עליון ב-Dpad"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"לחצן תחתון ב-Dpad"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"לחצן שמאלי ב-Dpad"</string>
@@ -2419,12 +2434,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"איך זה עובד"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"בהמתנה..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"הגדרה חוזרת של \'ביטול הנעילה בטביעת אצבע\'"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> לא פעלה טוב ולכן היא נמחקה"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ו<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> לא פעלו טוב ולכן הן נמחקו"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> לא פעלה היטב ולכן היא נמחקה. עליך להגדיר אותה שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות טביעת אצבע."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ו<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> לא פעלו היטב ולכן הן נמחקו. עליך להגדיר אותן שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות טביעת אצבע."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"הגדרה חוזרת של \'פתיחה ע\"י זיהוי הפנים\'"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"התבנית לזיהוי הפנים לא פעלה היטב ולכן היא נמחקה. עליך להגדיר אותה שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות זיהוי הפנים."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"הגדרה"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"לא עכשיו"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"שעון מעורר של <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"החלפת משתמש"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"השתקה"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"צריך להקיש כדי להשתיק את הצליל"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 934967f..e97ff00 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -156,8 +156,8 @@
<string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"モバイル ネットワーク セキュリティ"</string>
<string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"暗号化、暗号化されていないネットワークに関する通知"</string>
<string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"デバイス ID へのアクセスが発生しました"</string>
- <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に付近のネットワークでお使いのデバイスの一意の ID(IMSI または IMEI)が記録されました"</string>
- <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に付近のネットワークでお使いのデバイスの一意の ID(IMSI または IMEI)が記録されました。\n\nつまり、あなたの位置情報、アクティビティ、身元などが記録されことになります。これはよくある事象ですが、プライバシーに不安を持たれている人にとっては問題になる可能性があります。"</string>
+ <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に、お使いのデバイスの一意の ID(IMSI または IMEI)が付近のネットワークで記録されました。"</string>
+ <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に、お使いのデバイスの一意の ID(IMSI または IMEI)が付近のネットワークで記録されました。\n\nつまり、あなたの位置情報、アクティビティ、身元などが記録されたことになります。これはよくある事象ですが、プライバシーを保護したいユーザーにとっては問題となる可能性があります。"</string>
<string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"暗号化されたネットワーク(<xliff:g id="NETWORK_NAME">%1$s</xliff:g>)に接続しました"</string>
<string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> の SIM 接続のセキュリティが強化されました"</string>
<string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"接続先のネットワークが暗号化されていません"</string>
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"バグレポート"</string>
<string name="global_action_logout" msgid="6093581310002476511">"セッションを終了"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"画面の保存"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"バグレポート"</string>
<string name="bugreport_message" msgid="5212529146119624326">"現在のデバイスの状態に関する情報が収集され、その内容がメールで送信されます。バグレポートが開始してから送信可能な状態となるまでには多少の時間がかかりますのでご了承ください。"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"対話型レポート"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ワイヤレス デバッグを無効にするには選択します。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"テストハーネス モード有効"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"シリアル コンソールは有効です"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"シリアル コンソールを有効にすると、パフォーマンスに影響します。無効にするには、ブートローダーをチェックしてください。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"試験運用版 MTE を有効にしました"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"音量ボタンを離してください。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を有効にするには音量大と音量小の両方のボタンを 3 秒ほど長押ししてください。"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ユーザー補助機能ボタンをタップした場合に使用する機能を選択してください。"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ユーザー補助操作(2 本の指で画面の下から上にスワイプ)で使用する機能を選択してください。"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ユーザー補助操作(3 本の指で画面の下から上にスワイプ)で使用する機能を選択してください。"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"機能を切り替えるには、ユーザー補助機能ボタンを長押しします。"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"機能を切り替えるには、2 本の指で上にスワイプしたまま長押しします。"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"機能を切り替えるには、3 本の指で上にスワイプしたまま長押しします。"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"この機能は、ユーザー補助機能ボタンを次回タップした時に利用できるようになります"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"この機能は、このショートカットを次回使用した時に利用できるようになります。2 本の指で画面の下部から上にスワイプし、素早く離してください。"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"この機能は、このショートカットを次回使用した時に利用できるようになります。3 本の指で画面の下部から上にスワイプし、素早く離してください。"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"拡大"</string>
<string name="user_switched" msgid="7249833311585228097">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>に切り替えています…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"着信をスクリーニング中"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"カテゴリなし"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"プロモーション"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"ソーシャル"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ニュース"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"推奨事項"</string>
<string name="importance_from_user" msgid="2782756722448800447">"このような通知の重要度を設定します。"</string>
<string name="importance_from_person" msgid="4235804979664465383">"関係するユーザーのため、この設定は重要です。"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"カスタムアプリ通知"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"画面上のユーザー補助機能のショートカットの選択メニュー"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ユーザー補助のショートカット"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"通知シェードを閉じる"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"メニュー"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"メディアの再生 / 一時停止"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad: 上"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad: 下"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad: 左"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"仕組み"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"保留中..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"指紋認証をもう一度設定してください"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> は正常に機能せず、削除されました"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> と <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> は正常に機能せず、削除されました"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> が正常に機能せず、削除されました。指紋認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> と <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> が正常に機能せず、削除されました。指紋認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"顔認証をもう一度設定してください"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"顔モデルが正常に機能せず、削除されました。顔認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"後で"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> さんのアラーム"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ユーザーを切り替え"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ミュート"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"音声をミュートするにはタップします"</string>
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 013125e..967877c 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"ხარვეზის ანგარიში"</string>
<string name="global_action_logout" msgid="6093581310002476511">"სესიის დასრულება"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ეკრანის ანაბეჭდი"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"ხარვეზის ანგარიში"</string>
<string name="bugreport_message" msgid="5212529146119624326">"იგი შეაგროვებს ინფორმაციას თქვენი მოწყობილობის ამჟამინდელი მდგომარეობის შესახებ, რათა ის ელფოსტის შეტყობინების სახით გააგზავნოს. ხარვეზის ანგარიშის მომზადებასა და შეტყობინების გაგზავნას გარკვეული დრო სჭირდება. გთხოვთ, მოითმინოთ."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ინტერაქტიული ანგარიში"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"აირჩიეთ შეცდომების უსადენო გამართვის გასათიშად."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"რეჟიმი „გარემო ტესტირებისთვის“ ჩართულია"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"დააბრუნეთ ქარხნული პარამეტრები „გარემო ტესტირებისთვის“ რეჟიმის გასათიშად."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"სერიული კონსოლი ჩართულია"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"მუშაობა შეფერხებულია. გასათიშად მონიშნეთ ჩამტვირთავი."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ექსპერიმენტული MTE ჩართულია"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ხელი აუშვით ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-ის ჩასართველად, ხელმეორედ ხანგრძლივად დააჭირეთ ორივე ხმის ღილაკს 3 წამის განმავლობაში."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი ფუნქცია:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"აირჩიეთ მარტივი წვდომის ჟესტთან (ორი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი ფუნქცია:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"აირჩიეთ მარტივი წვდომის ჟესტთან (სამი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი ფუნქცია:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"სერვისების გადასართავად, ხანგრძლივად შეეხეთ მარტივი წვდომის ღილაკს."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ფუნქციების გადასართავად, ორი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ფუნქციების გადასართავად, სამი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე შეეხებით მარტივი წვდომის ღილაკს"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 2 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 3 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"გადიდება"</string>
<string name="user_switched" msgid="7249833311585228097">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>-ზე გადართვა…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"მიმდინარე ზარი"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"შემომავალი ზარების გაცხრილვა"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"კატეგორიის გარეშე"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"სარეკლამო აქციები"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"სოციალური ქსელები"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ახალი ამბები"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"რეკომენდაციები"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრა თქვენ მიერ."</string>
<string name="importance_from_person" msgid="4235804979664465383">"მნიშვნელოვანია ჩართული მომხმარებლების გამო."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"აპის მორგებული შეტყობინება"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"მისაწვდომობის ეკრანული მალსახმობის ამომრჩევი"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"მისაწვდომობის მალსახმობი"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"შეტყობინებების ფარდის დახურვა"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"მენიუ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"მედიის დაკვრა/დაპაუზება"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ზევით"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ქვევით"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad მარცხნივ"</string>
@@ -2411,19 +2426,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"კერძო სივრცე"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"სენსიტიური შეტყობინების კონტენტი დამალულია"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებიდან აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებისას აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"სატელიტთან ავტომატურად დაკავშირებულია"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"შეგიძლიათ გაგზავნოთ და მიიღოთ შეტყობინებები მობილური ან Wi-Fi ქსელის გარეშე"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"მუშაობის პრინციპი"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"მომლოდინე..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ანაბეჭდით განბლოკვის ხელახლა დაყენება"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> კარგად არ მუშაობდა და წაიშალა"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> კარგად არ მუშაობდნენ და წაიშალა"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> კარგად არ მუშაობდა და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი თითის ანაბეჭდის საშუალებით განბლოკოთ."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> კარგად არ მუშაობდნენ და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი თითის ანაბეჭდის საშუალებით განბლოკოთ."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"დააყენეთ სახით განბლოკვა ხელახლა"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"თქვენი სახის მოდელი კარგად არ მუშაობდა და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი სახის საშუალებით განბლოკოთ."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"დაყენება"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ახლა არა"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"მაღვიძარა <xliff:g id="USER_NAME">%s</xliff:g>-ისთვის"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"მომხმარებლის გადართვა"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"დადუმება"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"შეეხეთ ხმის დასადუმებლად"</string>
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 791644d..9d3ee992 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Вирус туралы хабарлау"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Сеансты аяқтау"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Скриншот"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Қате туралы есеп"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Құрылғының қазіргі күйі туралы ақпаратты жинап, электрондық хабармен жібереді. Есеп әзір болғанша біраз уақыт кетеді, шыдай тұрыңыз."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактивті есеп"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Сымсыз түзетуді өшіру үшін басыңыз."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сынақ бағдарламасы режимі қосылды"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялық консоль қосылды"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Өнімділікке әсер етеді. Өшіру үшін жүктегішті тексеріңіз."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Эксперименттік MTE қосылды"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дыбыс деңгейі пернелерін жіберіңіз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосу үшін дыбыс деңгейі пернесінің екеуін де қайтадан 3 секундқа басып тұрыңыз."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын функцияны таңдаңыз:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Арнайы мүмкіндіктер қимылымен (екі саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз) пайдаланатын функцияны таңдаңыз:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Арнайы мүмкіндіктер қимылымен (үш саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз) пайдаланатын функцияны таңдаңыз:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Бір функциядан екінші функцияға ауысу үшін \"Арнайы мүмкіндіктер\" түймесін түртіп, оны ұстап тұрыңыз."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Бір функциядан екінші функцияға ауысу үшін екі саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Бір функциядан екінші функцияға ауысу үшін үш саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ұлғайту"</string>
<string name="user_switched" msgid="7249833311585228097">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Қоңырау"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Келген қоңырауды сүзу"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Санатқа жатқызылмаған"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промонауқандар"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Әлеуметтік желі"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Жаңалықтар"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Ұсыныстар"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Сіз осы хабарландырулардың маңыздылығын орнатасыз."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Қатысты адамдарға байланысты бұл маңызды."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Арнаулы қолданба хабарландыруы"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Экрандағы арнайы мүмкіндіктерді жылдам қосу әрекетін таңдау"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Арнайы мүмкіндіктерді жылдам қосу"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Хабарландыру тақтасын жабу"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Mәзір"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиафайл ойнату/кідірту"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Жоғарғы Dpad түймесі"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Төменгі Dpad түймесі"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Сол жақ Dpad түймесі"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Бұл қалай орындалады?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Дайын емес…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> саусақ ізі дұрыс істемегендіктен жойылды."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Саусақ іздері (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) дұрыс істемегендіктен жойылды."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> саусақ ізі дұрыс істемегендіктен жойылды. Телефонды саусақ ізімен ашу үшін оны қайта реттеңіз."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Саусақ іздері (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) дұрыс істемегендіктен жойылды. Телефонды саусақ ізімен ашу үшін оларды қайта реттеңіз."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Бет тану функциясын қайта реттеу"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Бет үлгісі дұрыс істемегендіктен жойылды. Телефонды бетпен ашу үшін оны қайта реттеңіз."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Реттеу"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Қазір емес"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> атына қойылған дабыл"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Пайдаланушыны ауыстыру"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Дыбысын өшіру"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Дыбысын өшіру үшін түртіңіз."</string>
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 12e1a36..88bf527 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"របាយការណ៍កំហុស"</string>
<string name="global_action_logout" msgid="6093581310002476511">"បញ្ចប់សម័យ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"រូបថតអេក្រង់"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"របាយការណ៍អំពីបញ្ហា"</string>
<string name="bugreport_message" msgid="5212529146119624326">"វានឹងប្រមូលព័ត៌មានអំពីស្ថានភាពឧបករណ៍របស់អ្នក ដើម្បីផ្ញើជាសារអ៊ីមែល។ វានឹងចំណាយពេលតិចពីពេលចាប់ផ្ដើមរបាយការណ៍រហូតដល់ពេលវារួចរាល់ដើម្បីផ្ញើ សូមអត់ធ្មត់។"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"របាយការណ៍អន្តរកម្ម"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ជ្រើសរើស ដើម្បីបិទការជួសជុលដោយឥតខ្សែ។"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"បានបើកមុខងារប្រមូលធ្វើតេស្ត"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ធ្វើការកំណត់ដូចដើមឡើងវិញ ដើម្បីបិទមុខងារប្រមូលធ្វើតេស្ត។"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"កុងសូលស៊េរីត្រូវបានបើក"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ប្រតិបត្តិការទទួលរងការប៉ះពាល់។ សូមពិនិត្យមើលកម្មវិធីដំណើរការប្រព័ន្ធ ដើម្បីបិទ។"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"បានបើក MTE ពិសោធន៍"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"លែងគ្រាប់ចុចកម្រិតសំឡេង។ ដើម្បីបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g> សូមចុចគ្រាប់ចុចកម្រិតសំឡេងទាំងពីរឱ្យជាប់ម្ដងទៀតរយៈពេល 3 វិនាទី។"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ជ្រើសរើសមុខងារដែលត្រូវប្រើ នៅពេលដែលអ្នកចុចប៊ូតុងភាពងាយស្រួល៖"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ជ្រើសរើសមុខងារ ដើម្បីប្រើជាមួយចលនាភាពងាយស្រួល (អូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់ដោយប្រើម្រាមដៃពីរ)៖"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ជ្រើសរើសមុខងារ ដើម្បីប្រើជាមួយចលនាភាពងាយស្រួល (អូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់ដោយប្រើម្រាមដៃបី)៖"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ដើម្បីប្ដូររវាងមុខងារផ្សេងៗ សូមចុចប៊ូតុងភាពងាយស្រួលឱ្យជាប់។"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ដើម្បីប្ដូររវាងមុខងារផ្សេងៗ សូមអូសឡើងលើដោយប្រើម្រាមដៃពីរ ហើយសង្កត់ឱ្យជាប់។"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ដើម្បីប្ដូររវាងមុខងារផ្សេងៗ សូមអូសឡើងលើដោយប្រើម្រាមដៃបី ហើយសង្កត់ឱ្យជាប់។"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ការពង្រីក"</string>
<string name="user_switched" msgid="7249833311585228097">"អ្នកប្រើបច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
<string name="user_switching_message" msgid="1912993630661332336">"កំពុងប្ដូរទៅ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"ការហៅដែលកំពុងដំណើរការ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"កំពុងពិនិត្យការហៅចូល"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"មិនបែងចែកប្រភេទ"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ប្រូម៉ូសិន"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"សង្គម"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ព័ត៌មាន"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"ការណែនាំ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"អ្នកបានកំណត់សារៈសំខាន់នៃការជូនដំណឹងទាំងនេះ"</string>
<string name="importance_from_person" msgid="4235804979664465383">"វាមានសារៈសំខាន់ដោយសារតែមនុស្សដែលពាក់ព័ន្ធ"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ការជូនដំណឹងកម្មវិធីផ្ទាល់ខ្លួន"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ម៉ឺនុយជ្រើសរើសផ្លូវកាត់ភាពងាយស្រួលនៅលើអេក្រង់"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ផ្លូវកាត់ភាពងាយស្រួល"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ច្រានចោលផ្ទាំងជូនដំណឹង"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ម៉ឺនុយ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ចាក់/ផ្អាកមេឌៀ"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ឡើងលើ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ចុះក្រោម"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ឆ្វេង"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"របៀបដែលវាដំណើរការ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"កំពុងរង់ចាំ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"រៀបចំការដោះសោដោយស្កេនស្នាមម្រាមដៃម្ដងទៀត"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើស្នាមម្រាមដៃ។"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើស្នាមម្រាមដៃ។"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"រៀបចំការដោះសោដោយស្កេនមុខម្ដងទៀត"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"គំរូមុខរបស់អ្នកមិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើមុខ។"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"រៀបចំ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"កុំទាន់"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ម៉ោងរោទ៍សម្រាប់ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ប្ដូរអ្នកប្រើប្រាស់"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"បិទសំឡេង"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ចុចដើម្បីបិទសំឡេង"</string>
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c134b74..5961245 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"ದೋಷದ ವರದಿ"</string>
<string name="global_action_logout" msgid="6093581310002476511">"ಸೆಷನ್ ಅಂತ್ಯಗೊಳಿಸಿ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"ಬಗ್ ವರದಿ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ನಿಮ್ಮ ಸಾಧನದ ಪ್ರಸ್ತುತ ಸ್ಥಿತಿಯ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸಿಕೊಳ್ಳುವುದರ ಜೊತೆ ಇ-ಮೇಲ್ ರೂಪದಲ್ಲಿ ನಿಮಗೆ ರವಾನಿಸುತ್ತದೆ. ಇದು ದೋಷ ವರದಿಯನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಸಮಯದಿಂದ ಅದನ್ನು ಕಳುಹಿಸುವವರೆಗೆ ಸ್ವಲ್ಪ ಸಮಯವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ; ದಯವಿಟ್ಟು ತಾಳ್ಮೆಯಿಂದಿರಿ."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ಪರಸ್ಪರ ಸಂವಹನ ವರದಿ"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ವೈರ್ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಫ್ಯಾಕ್ಟರಿ ರಿಸೆಟ್ ಮಾಡಬೇಕು."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"ಸರಣಿ ಕನ್ಸೋಲ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ಕಾರ್ಯಕ್ಷಮತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ. ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು, ಬೂಟ್ಲೋಡರ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ಪ್ರಾಯೋಗಿಕ MTE ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಲಾಗಿದೆ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲು, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಮತ್ತೊಮ್ಮೆ 3 ಸೆಕೆಂಡ್ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ನೀವು ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆರಿಸಿ:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಗೆಸ್ಚರ್ನೊಂದಿಗೆ ಬಳಸಲು ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಗೆಸ್ಚರ್ನೊಂದಿಗೆ ಬಳಸಲು ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ವೈಶಿಷ್ಟ್ಯಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಬಟನ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ವೈಶಿಷ್ಟ್ಯಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ವೈಶಿಷ್ಟ್ಯಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಬಟನ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ 2 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ 3 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
<string name="user_switched" msgid="7249833311585228097">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ಕ್ರೀನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ವರ್ಗೀಕರಿಸದಿರುವುದು"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ಪ್ರೊಮೋಷನ್ಗಳು"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"ಸಾಮಾಜಿಕ"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ಸುದ್ದಿ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"ಶಿಫಾರಸುಗಳು"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ನೀವು ಈ ಅಧಿಸೂಚನೆಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಿರುವಿರಿ."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ಜನರು ತೊಡಗಿಕೊಂಡಿರುವ ಕಾರಣ ಇದು ಅತ್ಯಂತ ಪ್ರಮುಖವಾಗಿದೆ."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ಕಸ್ಟಮ್ ಆ್ಯಪ್ ನೋಟಿಫಿಕೇಶನ್"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ಸ್ಕ್ರೀನ್ನಲ್ಲಿನ ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಶಾರ್ಟ್ಕಟ್ ಆಯ್ಕೆ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಶಾರ್ಟ್ಕಟ್"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ಅಧಿಸೂಚನೆಯ ಪರದೆಯನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ಮೆನು"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ಮೀಡಿಯಾವನ್ನು ಪ್ಲೇ ಮಾಡಿ/ವಿರಾಮಗೊಳಿಸಿ"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ನ ಮೇಲಿನ ಬಟನ್"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ನ ಕೆಳಗಿನ ಬಟನ್"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ನ ಎಡಭಾಗದ ಬಟನ್"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ಬಾಕಿ ಉಳಿದಿದೆ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿರಲಿಲ್ಲ, ಹಾಗಾಗಿ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿರಲಿಲ್ಲ, ಹಾಗಾಗಿ ಅವುಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ಅದನ್ನು ಪುನಃ ಸೆಟಪ್ ಮಾಡಿ."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅವುಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ. ನಿಮ್ಮ ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ಅವುಗಳನ್ನು ಪುನಃ ಸೆಟಪ್ ಮಾಡಿ."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ಫೇಸ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಫೇಸ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ಅದನ್ನು ಪುನಃ ಸೆಟಪ್ ಮಾಡಿ."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ಸೆಟಪ್ ಮಾಡಿ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ಈಗ ಬೇಡ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> ಗಾಗಿ ಅಲಾರಾಂ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ಧ್ವನಿಯನ್ನು ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 62ec778..1dea620 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"버그 신고"</string>
<string name="global_action_logout" msgid="6093581310002476511">"세션 끝내기"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"스크린샷"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"버그 신고"</string>
<string name="bugreport_message" msgid="5212529146119624326">"현재 기기 상태에 대한 정보를 수집하여 이메일 메시지로 전송합니다. 버그 신고를 시작하여 전송할 준비가 되려면 약간 시간이 걸립니다."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"대화형 보고서"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"무선 디버깅을 사용 중지하려면 선택하세요."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"테스트 하네스 모드 사용 설정됨"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"테스트 하네스 모드를 사용 중지하려면 초기화하세요."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"시리얼 콘솔 사용 설정됨"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"성능에 영향을 미쳤습니다. 사용 중지하려면 부트로더를 확인하세요."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"실험용 MTE 사용 설정됨"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"볼륨 키에서 손을 뗍니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>을 켜려면 볼륨 키 2개를 3초 동안 길게 누르세요."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"접근성 버튼을 탭할 때 사용할 기능을 선택하세요."</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"접근성 동작(두 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 기능을 선택하세요."</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"접근성 동작(세 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 기능을 선택하세요."</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"기능 간에 전환하려면 접근성 버튼을 길게 터치합니다."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"기능 간에 전환하려면 두 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"기능 간에 전환하려면 세 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"확대"</string>
<string name="user_switched" msgid="7249833311585228097">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>로 전환하는 중…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"진행 중인 통화"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"수신 전화 검사 중"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"지정된 카테고리 없음"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"프로모션"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"소셜"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"뉴스"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"권장사항"</string>
<string name="importance_from_user" msgid="2782756722448800447">"이러한 알림의 중요도를 설정했습니다."</string>
<string name="importance_from_person" msgid="4235804979664465383">"관련된 사용자가 있으므로 중요합니다."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"맞춤 앱 알림"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"화면상의 접근성 바로가기 선택 도구"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"접근성 단축키"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"알림 창 닫기"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"메뉴"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"미디어 재생/일시중지"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"방향 패드 위쪽"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"방향 패드 아래"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"방향 패드 왼쪽"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"작동 방식"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"대기 중…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"지문 잠금 해제 다시 설정"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문이 제대로 작동하지 않아 삭제되었습니다."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문이 제대로 작동하지 않아 삭제되었습니다."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>이(가) 제대로 작동하지 않아 삭제되었습니다. 지문으로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>이(가) 제대로 작동하지 않아 삭제되었습니다. 지문으로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"얼굴 인식 잠금 해제 다시 설정"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"얼굴 모델이 제대로 작동하지 않아 삭제되었습니다. 얼굴로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"설정"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"나중에"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>님의 알람"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"사용자 전환"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"음소거"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"탭하여 소리 음소거"</string>
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 4df1e7e..4776793 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Ката тууралуу билдирүү"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Сеансты бүтүрүү"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Скриншот"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Мүчүлүштүк жөнүндө кабарлоо"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ушуну менен түзмөгүңүздүн учурдагы абалы тууралуу маалымат топтолуп, электрондук почта аркылуу жөнөтүлөт. Отчет даяр болгуча бир аз күтө туруңуз."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактивдүү кабар"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоону өчүрүңүз."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сыноо программасынын режими иштетилди"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сыноо программасынын режимин өчүрүү үчүн баштапкы параметрлерге кайтарыңыз."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялык консоль иштетилди"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Майнаптуулугуна таасири тиет. Өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Cынамык MTE иштетилди"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Үн баскычтарын коё бериңиз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүзүү үчүн үн баскычтарын кайра 3 секунд коё бербей басып туруңуз."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн функцияны тандаңыз (эки манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Атайын мүмкүнчүлүктөр жаңсоосу аркылуу иштетиле турган функцияны тандаңыз (үч манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Функцияларды которуштуруу үчүн, Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Функцияларды которуштуруу үчүн, эки манжаңыз менен өйдө сүрүп, кармап туруңуз."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Башка функцияга которулуу үчүн үч манжаңыз менен экранды өйдө сүрүп, кармап туруңуз."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Чоңойтуу"</string>
<string name="user_switched" msgid="7249833311585228097">"Учурдагы колдонуучу <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Учурдагы чалуу"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Кирүүчү чалууну иргөө"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Категорияларга бөлүнгөн эмес"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакциялар"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Коомдук тармактар"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Жаңылыктар"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Cунуштар"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Булар сиз үчүн маанилүү адамдар."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Колдонмонун ыңгайлаштырылган билдирмеси"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ыкчам иштетүү менюсу"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Ыкчам иштетүү"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Билдирмелер тактасын жабуу"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиа файлды ойнотуу/тындыруу"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad\'дын жогорку баскычы"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad\'дын ылдыйкы баскычы"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad\'дын сол баскычы"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ал кантип иштейт"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Манжа изи менен ачуу функциясын кайра тууралаңыз"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ойдогудай иштебегендиктен өчүрүлдү"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ойдогудай иштебегендиктен өчүрүлдү"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ойдогудай иштебегендиктен, жок кылынды. Телефондо Манжа изи менен ачуу функциясын колдонуу үчүн аны кайра тууралаңыз."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ойдогудай иштебегендиктен, жок кылынды. Телефонду манжа изи менен ачуу үчүн аларды кайра тууралаңыз."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Жүзүнөн таанып ачуу функциясын кайрадан тууралаңыз"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Жүзүңүздүн үлгүсү ойдогудай иштебегендиктен, жок кылынды. Телефондо Жүзүнөн таанып ачуу функциясын колдонуу үчүн аны кайра тууралаңыз."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тууралоо"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Азыр эмес"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> үчүн ойготкуч"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Колдонуучуну которуштуруу"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Үнүн басуу"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Үнүн басуу үчүн таптап коюңуз"</string>
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 3b77acb..7e31a1c 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"ລາຍງານຂໍ້ຜິດພາດ"</string>
<string name="global_action_logout" msgid="6093581310002476511">"ສິ້ນສຸດເຊດຊັນ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ພາບໜ້າຈໍ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"ລາຍງານຂໍ້ຜິດພາດ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ນີ້ຈະເປັນການເກັບກຳຂໍ້ມູນກ່ຽວກັບ ສະຖານະປັດຈຸບັນຂອງອຸປະກອນທ່ານ ເພື່ອສົ່ງເປັນຂໍ້ຄວາມທາງອີເມວ. ມັນຈະໃຊ້ເວລາໜ້ອຍນຶ່ງ ໃນການເລີ່ມຕົ້ນການລາຍງານຂໍ້ຜິດພາດ ຈົນກວ່າຈະພ້ອມທີ່ຈະສົ່ງໄດ້, ກະລຸນາລໍຖ້າ."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ລາຍງານແບບໂຕ້ຕອບ"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ເລືອກເພື່ອປິດການນຳໃຊ້ການດີບັກໄຮ້ສາຍ."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ເປີດໃຊ້ໂໝດ Test Harness ແລ້ວ"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"ເປີດນຳໃຊ້ຊີຣຽວຄອນໂຊແລ້ວ"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ມີຜົນກະທົບກັບປະສິດທິພາບ. ເພື່ອປິດການນຳໃຊ້, ໃຫ້ກວດສອບ bootloader ເບິ່ງ."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ເປີດການນຳໃຊ້ MTE ແບບທົດລອງແລ້ວ"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ປ່ອຍປຸ່ມລະດັບສຽງ. ເພື່ອເປີດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ໃຫ້ກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີ."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ເລືອກຄຸນສົມບັດທີ່ຈະໃຊ້ເມື່ອທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ເລືອກຄຸນສົມບັດເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສອງນິ້ວ):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ເລືອກຄຸນສົມບັດເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສາມນິ້ວ):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ເພື່ອສະຫຼັບລະຫວ່າງຄຸນສົມບັດຕ່າງໆ, ໃຫ້ແຕະໃສ່ປຸ່ມການຊ່ວຍເຂົ້າເຖິງຄ້າງໄວ້."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິຄຸນສົມບັດຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສອງນິ້ວຄ້າງໄວ້."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ເພື່ອສະຫຼັບລະຫວ່າງຄຸນສົມບັດຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສາມນິ້ວຄ້າງໄວ້."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ການຂະຫຍາຍ"</string>
<string name="user_switched" msgid="7249833311585228097">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
<string name="user_switching_message" msgid="1912993630661332336">"ກຳລັງສະຫຼັບໄປຫາ<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"ສາຍໂທອອກ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ກຳລັງກວດສອບສາຍໂທເຂົ້າ"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ບໍ່ມີໝວດໝູ່"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ໂປຣໂມຊັນ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"ສັງຄົມ"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ຂ່າວ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"ການແນະນຳ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ທ່ານຕັ້ງຄວາມສຳຄັນຂອງການແຈ້ງເຕືອນເຫຼົ່ານີ້."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ຂໍ້ຄວາມນີ້ສຳຄັນເນື່ອງຈາກບຸກຄົນທີ່ກ່ຽວຂ້ອງ."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ການແຈ້ງເຕືອນແອັບແບບກຳນົດເອງ"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ຕົວເລືອກທາງລັດການຊ່ວຍເຂົ້າເຖິງຢູ່ໜ້າຈໍ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ທາງລັດການຊ່ວຍເຂົ້າເຖິງ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ປິດເງົາການແຈ້ງເຕືອນໄວ້"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ເມນູ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ຫຼິ້ນ/ຢຸດສື່ຊົ່ວຄາວ"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ຂຶ້ນ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ລົງ"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ຊ້າຍ"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ມັນເຮັດວຽກແນວໃດ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ລໍຖ້າດຳເນີນການ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືຄືນໃໝ່"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍລາຍນິ້ວມື."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າພວກມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍລາຍນິ້ວມື."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າຄືນໃໝ່"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ຮູບແບບໃບໜ້າຂອງທ່ານເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍໃບໜ້າ."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ຕັ້ງຄ່າ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ບໍ່ຟ້າວເທື່ອ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ໂມງປຸກສຳລັບ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ສະຫຼັບຜູ້ໃຊ້"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ປິດສຽງ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ແຕະເພື່ອປິດສຽງ"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index b864773..87027a6 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Pranešimas apie riktą"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Baigti seansą"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Ekrano kopija"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Pranešim. apie riktą"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Bus surinkta informacija apie dabartinę įrenginio būseną ir išsiųsta el. pašto pranešimu. Šiek tiek užtruks, kol pranešimas apie riktą bus paruoštas siųsti; būkite kantrūs."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interakt. ataskaita"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pasirinkite, kad išjungtumėte belaidžio ryšio derinimą."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testavimo sistemos režimas įgalintas"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Atkurkite gamyklinius duomenis, kad išjungtumėte testavimo sistemos režimą."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijos pultas įgalintas"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Našumas paveiktas. Norėdami išjungti, patikrinkite paleidyklę."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentiniai atminties žymėjimo plėtiniai (angl. „Memory Tagging Extensions“, MTE) įgalinti"</string>
@@ -1757,12 +1763,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atleiskite garsumo klavišus. Kad įjungtumėte „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite ir 3 sekundes palaikykite garsumo klavišus."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pasirinkite funkciją, kuri bus naudojama, kai paliesite pritaikomumo mygtuką:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pasirinkite funkciją, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn dviem pirštais iš ekrano apačios):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pasirinkite funkciją, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn trimis pirštais iš ekrano apačios):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Norėdami perjungti funkcijas, palieskite ir palaikykite pritaikomumo mygtuką."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Norėdami perjungti funkcijas, perbraukite aukštyn dviem pirštais ir palaikykite."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Norėdami perjungti funkcijas, perbraukite aukštyn trimis pirštais ir palaikykite."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Didinimas"</string>
<string name="user_switched" msgid="7249833311585228097">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1990,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Vykstantis skambutis"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Gaunamojo skambučio tikrinimas"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Be kategorijos"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Akcijos"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Socialiniai tinklai"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Naujienos"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomendacijos"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Galite nustatyti šių pranešimų svarbą."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Tai svarbu dėl susijusių žmonių."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tinkintas programos pranešimas"</string>
@@ -2194,6 +2210,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekrano pritaikomumo šaukinių parinkiklis"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pritaikomumo šaukinys"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Atsisakyti pranešimų skydelio"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meniu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Leisti / pristabdyti mediją"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Valdymo pultas – aukštyn"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Valdymo pultas – žemyn"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Valdymo pultas – kairėn"</string>
@@ -2420,12 +2438,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kaip tai veikia"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Laukiama..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Atrakinimo piršto atspaudu nustatymas dar kartą"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> neveikė tinkamai ir buvo ištrintas"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> neveikė tinkamai ir buvo ištrinti"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> neveikė tinkamai ir buvo ištrintas. Nustatykite jį dar kartą, kad atrakintumėte telefoną piršto atspaudu."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> neveikė tinkamai ir buvo ištrinti. Nustatykite juos dar kartą, kad atrakintumėte telefoną piršto atspaudu."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Atrakinimo pagal veidą nustatymas iš naujo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jūsų veido modelis neveikė tinkamai ir buvo ištrintas. Nustatykite jį dar kartą, kad atrakintumėte telefoną pagal veidą."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nustatyti"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne dabar"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Signalas: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Perjungti naudotoją"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Nutildyti"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Palieskite, kad nutildytumėte garsą"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9147e9b..3bd986e 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Kļūdu ziņojums"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Beigt sesiju"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Ekrānuzņēmums"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Kļūdas pārskats"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Veicot šo darbību, tiks apkopota informācija par jūsu ierīces pašreizējo stāvokli un nosūtīta e-pasta ziņojuma veidā. Kļūdu ziņojuma pabeigšanai un nosūtīšanai var būt nepieciešams laiks. Lūdzu, esiet pacietīgs."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktīvs pārskats"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Atlasiet, lai atspējotu bezvadu atkļūdošanu."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Drošības pārbaudes režīms ir iespējots"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Lai atspējotu drošības pārbaudes režīmu, veiciet rūpnīcas datu atiestatīšanu."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriālā konsole ir iespējota"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Tiek ietekmēta veiktspēja. Lai atspējotu, pārbaudiet operētājsistēmu ielādes rīku."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentālais paplašinājums MTE iespējots"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atlaidiet skaļuma pogas. Lai ieslēgtu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vēlreiz nospiediet un trīs sekundes turiet nospiestas abas skaļuma pogas."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pieejamības pogai."</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar diviem pirkstiem augšup no ekrāna apakšdaļas)."</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar trīs pirkstiem augšup no ekrāna apakšdaļas)."</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Lai pārslēgtu funkcijas, pieskarieties pieejamības pogai un turiet to."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Lai pārslēgtu funkcijas, velciet ar diviem pirkstiem augšup un turiet."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Lai pārslēgtu funkcijas, velciet ar trīs pirkstiem augšup un turiet."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Palielinājums"</string>
<string name="user_switched" msgid="7249833311585228097">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pašreizējais zvans"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Ienākošā zvana filtrēšana"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nav kategorijas"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Akcijas"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sociālie tīkli"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Ziņas"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Ieteikumi"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Jūs iestatījāt šo paziņojumu svarīguma līmeni."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Tas ir svarīgi iesaistīto personu dēļ."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Pielāgots lietotnes paziņojums"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekrāna pieejamības saīsnes atlasītājs"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pieejamības saīsne"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Nerādīt paziņojumu paneli"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Izvēlne"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Sākt/apturēt multivides atskaņošanu"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Virzienu slēdzis — augšup"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Virzienu slēdzis — lejup"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Virzienu slēdzis — pa kreisi"</string>
@@ -2419,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Darbības principi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nedarbojās pareizi un tika izdzēsts"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nedarbojās pareizi un tika izdzēsti"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nedarbojās pareizi un tika izdzēsts. Iestatiet to atkal, lai varētu atbloķēt tālruni ar pirksta nospiedumu."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nedarbojās pareizi un tika izdzēsti. Iestatiet tos atkal, lai varētu atbloķētu tālruni ar pirksta nospiedumu."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vēlreiz iestatiet autorizāciju pēc sejas"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jūsu sejas modelis nedarbojās pareizi un tika izdzēsts. Iestatiet to atkal, lai varētu atbloķēt tālruni ar seju."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Iestatīt"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne tagad"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Signāls lietotājam <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Mainīt lietotāju"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Izslēgt skaņu"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Pieskarieties, lai izslēgtu skaņu"</string>
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index d305c87..afcf2d5 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Извештај за грешка"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Завршете ја сесијата"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Слика од екранот"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Извештај за грешки"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ова ќе собира информации за моменталната состојба на вашиот уред, за да ги испрати како порака по е-пошта. Тоа ќе одземе малку време почнувајќи од извештајот за грешки додека не се подготви за праќање; бидете трпеливи."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактивен извештај"</string>
@@ -1242,7 +1244,7 @@
<string name="alwaysUse" msgid="3153558199076112903">"Користи ја стандардно за ова дејство."</string>
<string name="use_a_different_app" msgid="4987790276170972776">"Користи различна апликација"</string>
<string name="clearDefaultHintMsg" msgid="1325866337702524936">"Избриши ги стандардните вредности во Системски поставки > Апликации > Преземено."</string>
- <string name="chooseActivity" msgid="8563390197659779956">"Избери дејство"</string>
+ <string name="chooseActivity" msgid="8563390197659779956">"Изберете дејство"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"Изберете апликација за USB-уредот"</string>
<string name="noApplications" msgid="1186909265235544019">"Нема апликации што можат да го извршат ова дејство."</string>
<string name="aerr_application" msgid="4090916809370389109">"<xliff:g id="APPLICATION">%1$s</xliff:g> запре"</string>
@@ -1310,7 +1312,7 @@
<string name="dump_heap_text" msgid="1692649033835719336">"Процесот <xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето за меморија од <xliff:g id="SIZE">%2$s</xliff:g>. Слика од меморијата ви е достапна за споделување со програмерот. Бидете внимателни: оваа слика од меморијата може да ги содржи сите лични информации до коишто апликацијата има пристап."</string>
<string name="dump_heap_system_text" msgid="6805155514925350849">"Процесот <xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето за меморија од <xliff:g id="SIZE">%2$s</xliff:g>. Слика од меморијата ви е достапна за споделување. Бидете внимателни: оваа слика од меморијата може да содржи чувствителни лични информации до коишто процесот има пристап, што може да вклучуваат работи што сте ги напишале."</string>
<string name="dump_heap_ready_text" msgid="5849618132123045516">"Слика од меморијата на <xliff:g id="PROC">%1$s</xliff:g> ви е достапна за споделување. Бидете внимателни: оваа слика од меморијата можеби ги содржи сите чувствителни лични информации до коишто процесот има пристап, што може да вклучуваат работи што сте ги напишале."</string>
- <string name="sendText" msgid="493003724401350724">"Избери дејство за текст"</string>
+ <string name="sendText" msgid="493003724401350724">"Изберете дејство за текст"</string>
<string name="volume_ringtone" msgid="134784084629229029">"Јачина на звук на ѕвонче"</string>
<string name="volume_music" msgid="7727274216734955095">"Јачина на звук за аудио/видео"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Се репродуцира преку Bluetooth"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изберете за да се оневозможи безжично отстранување грешки."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Овозможен е режимот на рамка за тестирање"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Извршете фабричко ресетирање за да го оневозможите режимот на рамка за тестирање."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериската конзола е овозможена"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Перформансите се засегнати. За да оневозможите, проверете го подигнувачот."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Овозможена е експериментална MTE"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е вклучена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е исклучена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ослободете ги копчињата за јачина на звукот. Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од 3 секунди за да вклучите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изберете функција за користење кога ќе го допрете копчето за пристапност:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со два прста):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со три прста):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"За префрлање помеѓу функциите, допрете и задржете го копчето за пристапност."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За да се префрлите на друга функција, повлечете нагоре со два прста и задржете."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За префрлање помеѓу функциите, повлечете нагоре со три прста и задржете."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Зголемување"</string>
<string name="user_switched" msgid="7249833311585228097">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Се префрла на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Тековен повик"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Проверка на дојдовен повик"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризирано"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоции"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Друштвени"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Вести"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Препораки"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ја поставивте важноста на известувањава."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ова е важно заради луѓето кои се вклучени."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Приспособено известување за апликација"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Избирач на кратенка за пристапност на екранот"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Кратенка за пристапност"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Отфрлете го панелот за известување"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Мени"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Пушти/паузирај аудиовизуелни содржини"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Навигациско копче за нагоре"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Навигациско копче за надолу"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Навигациско копче за налево"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Дознајте како функционира"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Во фаза на чекање…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поставете „Отклучување со отпечаток“ повторно"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> не функционираше добро, па се избриша"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> не функционираа добро, па се избришаа"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> не функционираше добро, па се избриша. Поставете го повторно за да го отклучувате телефонот со отпечаток."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> не функционираа добро, па се избришаа. Поставете ги повторно за да го отклучувате телефонот со отпечаток."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Поставете „Отклучување со лик“ повторно"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Вашиот модел на лик не функционираше добро, па се избриша. Поставете го повторно за да го отклучите телефонот со лик."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Поставете"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Аларм за <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Сменете го корисникот"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Исклучи звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Допрете за да го исклучите звукот"</string>
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index ede15a1..7cac60a 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"ബഗ് റിപ്പോർട്ട്"</string>
<string name="global_action_logout" msgid="6093581310002476511">"സെഷൻ അവസാനിപ്പിക്കുക"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"സ്ക്രീൻഷോട്ട്"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"ബഗ് റിപ്പോർട്ട്"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ഒരു ഇമെയിൽ സന്ദേശമായി അയയ്ക്കുന്നതിന്, ഇത് നിങ്ങളുടെ നിലവിലെ ഉപകരണ നിലയെക്കുറിച്ചുള്ള വിവരങ്ങൾ ശേഖരിക്കും. ബഗ് റിപ്പോർട്ട് ആരംഭിക്കുന്നതിൽ നിന്ന് ഇത് അയയ്ക്കാനായി തയ്യാറാകുന്നതുവരെ അൽപ്പസമയമെടുക്കും; ക്ഷമയോടെ കാത്തിരിക്കുക."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ഇന്റരാക്റ്റീവ് റിപ്പോർട്ട്"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"വയർലെസ് ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"പരിശോധനാ സംവിധാനങ്ങൾ മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"പരിശോധനാ സംവിധാന മോഡ് പ്രവർത്തനരഹിതമാക്കാൻ ഫാക്ടറി പുനഃക്രമീകരണം നിർവഹിക്കുക."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"സീരിയൽ കൺസോൾ പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"പ്രകടനത്തെ ബാധിച്ചു. പ്രവർത്തനരഹിതമാക്കാൻ, ബൂട്ട് ലോഡർ പരിശോധിക്കുക."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"പരീക്ഷണാത്മക MTE പ്രവർത്തനക്ഷമമാക്കി"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"വോളിയം കീകൾ വിടുക. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കാൻ, രണ്ട് വോളിയം കീകളും വീണ്ടും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കുന്നതിന് ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക (രണ്ട് വിരലുകളുപയോഗിച്ച് സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക (മൂന്ന് വിരലുകളുപയോഗിച്ച് സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ഫീച്ചറുകൾക്കിടയിൽ മാറാൻ, ഉപയോഗസഹായി ബട്ടൺ സ്പർശിച്ച് പിടിക്കുക."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ഫീച്ചറുകൾക്കിടയിൽ മാറാൻ, രണ്ട് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്ത് പിടിക്കുക."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ഫീച്ചറുകൾക്കിടയിൽ മാറാൻ, മൂന്ന് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്ത് പിടിക്കുക."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"മാഗ്നിഫിക്കേഷൻ"</string>
<string name="user_switched" msgid="7249833311585228097">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="NAME">%1$s</xliff:g> ആണ്."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിലേക്ക് മാറുന്നു…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"സജീവമായ കോൾ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ഇൻകമിംഗ് കോൾ സ്ക്രീൻ ചെയ്യുന്നു"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"വർഗ്ഗീകരിച്ചിട്ടില്ലാത്ത"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"പ്രമോഷനുകൾ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"സാമൂഹികം"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"വാർത്തകൾ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"നിർദ്ദേശങ്ങൾ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ഈ അറിയിപ്പുകളുടെ പ്രാധാന്യം നിങ്ങൾ സജ്ജീകരിച്ചു."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ഉൾപ്പെട്ടിട്ടുള്ള ആളുകളെ കണക്കിലെടുക്കുമ്പോള് ഇത് പ്രധാനപ്പെട്ടതാണ്."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ഇഷ്ടാനുസൃത ആപ്പ് അറിയിപ്പുകൾ"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"സ്ക്രീനിലെ ഉപയോഗസഹായി കുറുക്കുവഴി ചൂസർ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ഉപയോഗസഹായി കുറുക്കുവഴി"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"അറിയിപ്പ് ഷെയ്ഡ് ഡിസ്മിസ് ചെയ്യുക"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"മെനു"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"മീഡിയ പ്ലേ ചെയ്യുക/താൽക്കാലികമായി നിർത്തുക"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad അപ്പ്"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ഡൗൺ"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ലെഫ്റ്റ്"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"സ്വകാര്യ സ്പേസ്"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"സൂക്ഷ്മമായി കൈകാര്യം ചെയ്യേണ്ട അറിയിപ്പ് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ആപ്പ് ഉള്ളടക്കം, അതിന്റെ സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് മറച്ചിരിക്കുന്നു"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് ആപ്പ് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"സാറ്റലൈറ്റിലേക്ക് സ്വയമേവ കണക്റ്റ് ചെയ്തു"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"മൊബൈലോ വൈഫൈ നെറ്റ്വർക്കോ ഇല്ലാതെ തന്നെ സന്ദേശങ്ങൾ അയയ്ക്കാനും സ്വീകരിക്കാനും നിങ്ങൾക്ക് കഴിയും"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ഇത് പ്രവർത്തിക്കുന്നത് എങ്ങനെയാണ്"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"തീർപ്പാക്കിയിട്ടില്ല..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അവ ഇല്ലാതാക്കി"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി. നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി വീണ്ടും സജ്ജീകരിക്കുക."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അവ ഇല്ലാതാക്കി. നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി അവ വീണ്ടും സജ്ജീകരിക്കുക."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ഫെയ്സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"നിങ്ങളുടെ മുഖ മോഡൽ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി. നിങ്ങളുടെ മുഖം ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി വീണ്ടും സജ്ജീകരിക്കുക."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"സജ്ജീകരിക്കുക"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ഇപ്പോൾ വേണ്ട"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> എന്നയാൾക്കുള്ള അലാറം"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ഉപയോക്താവിനെ മാറുക"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"മ്യൂട്ടുചെയ്യുക"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ശബ്ദം മ്യൂട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 955b025..7a2fa53 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Алдаа мэдээлэх"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Гаргах харилцан үйлдэл"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Дэлгэцийн зураг дарах"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Алдааны мэдээ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Энэ таны төхөөрөмжийн одоогийн статусын талаарх мэдээллийг цуглуулах ба имэйл мессеж болгон илгээнэ. Алдааны мэдэгдлээс эхэлж илгээхэд бэлэн болоход хэсэг хугацаа зарцуулагдана тэвчээртэй байна уу."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактив тайлан"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Wireless debugging-г идэвхгүй болгохын тулд сонгоно уу."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Туршилтын цогц горимыг идэвхжүүлсэн"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Туршилтын цогц горимыг идэвхгүй болгохын тулд үйлдвэрийн төлөвт шинэчилнэ үү."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Цуваа консолыг идэвхжүүлсэн"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Гүйцэтгэлд нөлөөлнө. Идэвхгүй болгохын тулд эхэлж ачаалагчийг шалгана уу."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Туршилтын MTE-г идэвхжүүлсэн"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаалаа."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраалаа."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дууны түвшний товчнуудыг суллана уу. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаахын тулд дууны түвшний 2 товчийг зэрэг 3 секундийн турш удаан дарна уу."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Хандалтын товчлуурыг товшихдоо ашиглах онцлогийг сонгоно уу:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Хандалтын зангаагаар ашиглах үйлчилгээг сонгоно уу (хоёр хуруугаараа дэлгэцийн доороос дээш хоёр хуруугаар шударна уу):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Хандалтын зангаагаар ашиглах онцлогийг сонгоно уу (гурван хуруугаар дэлгэцийн доороос дээш шударна уу):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Онцлогуудын хооронд сэлгэхийн тулд хандалтын товчлуурыг удаан дарна уу."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Онцлогуудын хооронд сэлгэхийн тулд хоёр хуруугаар дээш шудраад удаан дарна уу."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Онцлогуудын хооронд сэлгэхийн тулд гурван хуруугаар дээш шудраад удаан дарна уу."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Томруулах"</string>
<string name="user_switched" msgid="7249833311585228097">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Дуудлага хийгдэж байна"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Ирсэн дуудлагыг харуулж байна"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Ангилаагүй"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Урамшуулал"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Сошиал"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Мэдээ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Зөвлөмж"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Та эдгээр мэдэгдлийн ач холбогдлыг тогтоосон."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Аппын захиалгат мэдэгдэл"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Дэлгэц дээрх хандалтын товчлол сонгогч"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хандалтын товчлол"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Мэдэгдлийн хураангуй самбарыг хаах"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Цэс"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиаг тоглуулах/түр зогсоох"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad дээш"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad доош"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad зүүн"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Хаалттай орон зай"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Эмзэг мэдэгдлийн контентыг нуусан"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын улмаас аппын контентыг дэлгэц хуваалцахаас нуусан"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын үүднээс аппын контентыг дэлгэц хуваалцахаас нуусан"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Хиймэл дагуулд автоматаар холбогдсон"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Та мобайл эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах боломжтой"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Энэ хэрхэн ажилладаг вэ?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> сайн ажиллахгүй байсан тул хурууны хээг устгасан"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> сайн ажиллахгүй байсан тул эдгээр хурууны хээг устгасан"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> сайн ажиллахгүй байсан тул үүнийг устгасан. Утасныхаа түгжээг хурууны хээгээр тайлахын тулд хурууны хээг дахин тохируулна уу."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> сайн ажиллахгүй байсан тул эдгээрийг устгасан. Утасныхаа түгжээг хурууныхаа хээгээр тайлахын тулд хоёр хурууны хээг дахин тохируулна уу."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Царайгаар түгжээ тайлахыг дахин тохируулна уу"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Таны нүүрний загвар сайн ажиллахгүй байсан бөгөөд үүнийг устгасан. Утасныхаа түгжээг царайгаар тайлахын тулд нүүрний загварыг дахин тохируулна уу."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тохируулах"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Одоо биш"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-н сэрүүлэг"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Хэрэглэгч сэлгэх"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Дууг хаах"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Дууг хаахын тулд товшино уу"</string>
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 2df1bc9..f811004 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"बग रिपोर्ट"</string>
<string name="global_action_logout" msgid="6093581310002476511">"सेशन समाप्त करा"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"स्क्रीनशॉट"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"बग रिपोर्ट"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ईमेल मेसेज म्हणून पाठविण्यासाठी, हे तुमच्या सध्याच्या डिव्हाइस स्थितीविषयी माहिती संकलित करेल. बग रिपोर्ट सुरू करण्यापासून तो पाठवण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"परस्परसंवादी अहवाल"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वायरलेस डीबगिंग बंद करण्यासाठी निवडा."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"टेस्ट हार्नेस मोड सुरू केला आहे"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"टेस्ट हार्नेस मोड बंद करण्यासाठी फॅक्टरी रीसेट करा."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"सिरीअल कन्सोल सुरू केला आहे"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"परफॉर्मन्सवर परिणाम होतो. बंद करण्यासाठी, बूटलोडर तपासा."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"प्रायोगिक MTE सुरू केले आहे"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"व्हॉल्यूम की रिलीझ करा. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू करण्यासाठी, दोन्ही व्हॉल्यूम की पुन्हा प्रेस करा आणि तीन सेकंदांसाठी धरून ठेवा."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तुम्ही अॅक्सेसिबिलिटी बटणावर टॅप केल्यास वापरण्यासाठी एक वैशिष्ट्य निवडा:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"अॅक्सेसिबिलिटी जेश्चरसोबत वापराचे असलेले वैशिष्ट्य निवडा (दोन बोटांनी स्क्रीनच्या तळापासून वर स्वाइप करा):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"अॅक्सेसिबिलिटी जेश्चरसोबत वापराचे असलेले वैशिष्ट्य निवडा (तीनन बोटांनी स्क्रीनच्या तळापासून वर स्वाइप करा):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"वैशिष्टयांदरम्यान स्विच करण्यासाठी अॅक्सेसिबिलिटी बटणाला स्पर्श करा आणि धरून ठेवा."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"वैशिष्टयांदरम्यान स्विच करण्यासाठी दोन बोटांनी वर स्वाइप करा आणि धरून ठेवा."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"वैशिष्टयांदरम्यान स्विच करण्यासाठी तीन बोटांनी वर स्वाइप करा आणि धरून ठेवा."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"तुम्ही पुढील वेळी अॅक्सेसिबिलिटी बटणावर टॅप कराल, तेव्हा वैशिष्ट्य उघडेल"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. २ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. ३ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"मॅग्निफिकेशन"</string>
<string name="user_switched" msgid="7249833311585228097">"वर्तमान वापरकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"सुरू असलेला कॉल"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल स्क्रीन करत आहे"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"वर्गीकरण न केलेले"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"प्रमोशन"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"सोशल"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"बातम्या"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"शिफारशी"</string>
<string name="importance_from_user" msgid="2782756722448800447">"तुम्ही या सूचनांचे महत्त्व सेट केले."</string>
<string name="importance_from_person" msgid="4235804979664465383">"सामील असलेल्या लोकांमुळे हे महत्वाचे आहे."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"कस्टम ॲप सूचना"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ऑन-स्क्रीन ॲक्सेसिबिलिटी शॉर्टकट निवडकर्ता"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"अॅक्सेसिबिलिटी शॉर्टकट"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"सूचना शेड डिसमिस करा"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"मेनू"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"मीडिया प्ले करा/थांबवा"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad चे वरील"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad चे खालचे"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad डावीकडील"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ते कसे काम करते"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रलंबित आहे..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिंट अनलॉक पुन्हा सेट करा"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> योग्यरीत्या काम करत नव्हती, त्यामुळे ती हटवली आहे"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> योग्यरीत्या काम करत नव्हत्या, त्यामुळे त्या हटवल्या आहेत"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"योग्यरीत्या काम करत नसल्यामुळे <xliff:g id="FINGERPRINT">%s</xliff:g> हटवले गेले आहे. तुमचे फिंगरप्रिंट वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"परफॉर्मन्समध्ये सुधारणा करण्यासाठी आणि योग्यरीत्या काम करत नसल्यामुळे <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> व <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> हटवली गेली आहेत. तुमचे फिंगरप्रिंट वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलॉक पुन्हा सेट करा"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तुमचे फेस मॉडेल योग्यरीत्या काम करत नसल्यामुळे ते हटवले गेले आहे. तुमचा चेहरा वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट करा"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"आताच नको"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> साठी अलार्म"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"वापरकर्ता स्विच करा"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्यूट करा"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"आवाज म्यूट करण्यासाठी टॅप करा"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 31180be..0bd939ec 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Laporan pepijat"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Tamatkan sesi"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Tangkapan skrin"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Laporan pepijat"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ini akan mengumpul maklumat tentang keadaan peranti semasa anda untuk dihantarkan sebagai mesej e-mel. Harap bersabar, mungkin perlu sedikit masa untuk memulakan laporan sehingga siap untuk dihantar."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Laporan interaktif"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pilih untuk melumpuhkan penyahpepijatan wayarles."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mod Abah-abah Ujian didayakan"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Laksanakan tetapan semula kilang untuk melumpuhkan Mod Abah-abah Ujian."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Konsol bersiri didayakan"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Prestasi terjejas. Untuk melumpuhkan, semak pemuat but."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Percubaan MTE didayakan"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan kekunci kelantangan. Untuk menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, sila tekan dan tahan kedua-dua kekunci kelantangan sekali lagi selama 3 saat."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pilih ciri yang hendak digunakan apabila anda mengetik butang kebolehaksesan:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pilih ciri untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan dua jari):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pilih ciri untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan tiga jari):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Untuk beralih antara ciri, sentuh & tahan butang kebolehaksesan."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Untuk beralih antara ciri, leret ke atas menggunakan dua jari dan tahan."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Untuk beralih antara ciri, leret ke atas menggunakan tiga jari dan tahan."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Ciri ini akan dibuka pada kali seterusnya anda mengetik butang kebolehaksesan"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 2 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 3 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string>
<string name="user_switched" msgid="7249833311585228097">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Beralih kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Tidak dikategorikan"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosi"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosial"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Berita"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Syor"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Anda menetapkan kepentingan pemberitahuan ini."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Mesej ini penting disebabkan orang yang terlibat."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Pemberitahuan apl tersuai"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pemilih Pintasan Kebolehaksesan Pada Skrin"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pintasan Kebolehaksesan"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ketepikan Bidai Pemberitahuan"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Mainkan/Jeda Media"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Atas"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Bawah"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Kiri"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara ciri ini berfungsi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Belum selesai..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Sediakan Buka Kunci Cap Jari sekali lagi"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan. Sediakan cap jari sekali lagi untuk membuka kunci telefon anda menggunakan cap jari."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan. Sediakan kedua-dua cap jari tersebut sekali lagi untuk membuka kunci telefon anda menggunakan cap jari anda."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Sediakan semula Buka Kunci Wajah"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model wajah anda tidak berfungsi dengan baik dan telah dipadamkan. Sediakan model wajah sekali lagi untuk membuka kunci telefon anda menggunakan wajah."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sediakan"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Bukan sekarang"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Penggera untuk <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Tukar pengguna"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Redam"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ketik untuk meredamkan bunyi"</string>
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f1ab9e0..29efeed 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"အမှားရှာပြင် မှတ်တမ်း"</string>
<string name="global_action_logout" msgid="6093581310002476511">"စက်ရှင် ပြီးဆုံးပြီ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"ချွတ်ယွင်းချက်အစီရင်ခံစာ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"လက်ငင်းတုံ့ပြန်နိုင်သည့် အစီရင်ခံချက်"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"\'စမ်းသပ်ခြင်းစနစ်မုဒ်\' ဖွင့်ထားသည်"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"\'စမ်းသပ်ခြင်းစနစ် မုဒ်\' ကိုပိတ်ရန် စက်ရုံထုတ်အတိုင်း ပြင်ဆင်သတ်မှတ်ပါ။"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"အမှတ်စဉ် ကွန်ဆိုးလ်ကို ဖွင့်ထားသည်"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"စွမ်းဆောင်ရည်အပေါ် သက်ရောက်မှုရှိနိုင်ပါသည်။ ပိတ်ရန် bootloader ကို စစ်ဆေးပါ။"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"အစမ်းသုံး MTE ကို ဖွင့်ထားသည်"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"အသံထိန်းခလုတ်များကို လွှတ်လိုက်ပါ။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်ရန် အသံထိန်းခလုတ်နှစ်ခုစလုံးကို ၃ စက္ကန့်ကြာအောင် ထပ်နှိပ်ပါ။"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"သုံးနိုင်မှုခလုတ်ကို တို့ပြီးလျှင် ဝန်ဆောင်မှုတစ်ခု ရွေးပါ−"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"သုံးနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (ဖန်သားပြင်အောက်ခြေမှနေ၍ လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"သုံးနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (ဖန်သားပြင်အောက်ခြေမှနေ၍ လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် အများသုံးစွဲနိုင်မှုခလုတ်ကို ဖိထားပါ။"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"နောက်တစ်ကြိမ်တွင် သုံးနိုင်မှုခလုတ်ကို တို့သည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၂ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၃ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ချဲ့ခြင်း"</string>
<string name="user_switched" msgid="7249833311585228097">"လက်ရှိအသုံးပြုနေသူ <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေသည်…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"လက်ရှိခေါ်ဆိုမှု"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"အဝင်ခေါ်ဆိုမှုကို စစ်ဆေးနေသည်"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"အမျိုးအစားမခွဲရသေးပါ"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ပရိုမိုးရှင်းများ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"လူမှုရေး"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"သတင်း"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"အကြံပြုချက်များ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ဤသတိပေးချက်များ၏ အရေးပါမှုကိုသတ်မှတ်ပြီးပါပြီ။"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ပါဝင်သည့်လူများကြောင့် အရေးပါပါသည်။"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"စိတ်ကြိုက်အက်ပ် အကြောင်းကြားချက်"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ဖန်သားပြင်အတွက် အများသုံးစွဲနိုင်မှုဖြတ်လမ်းလင့်ခ် ရွေးချယ်စနစ်"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"အများသုံးနိုင်မှု ဖြတ်လမ်းလင့်ခ်"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"အကြောင်းကြားစာအကွက်ကို ပယ်ရန်"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"မီနူး"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"မီဒီယာ ဖွင့်ရန်/ခဏရပ်ရန်"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad အပေါ်"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad အောက်"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ဘယ်"</string>
@@ -2411,19 +2426,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"သီးသန့်နေရာ"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"သတိထားရမည့် အကြောင်းကြားချက်ပါ အချက်အလက်ကို ဖျောက်ထားသည်"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"အက်ပ်အကြောင်းအရာသည် လုံခြုံရေးအတွက် မျက်နှာပြင် မျှဝေခြင်းမှ ဖျောက်ထားသည်"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"လုံခြုံရေးအတွက် အက်ပ်အကြောင်းအရာကို ဖန်သားပြင် မျှဝေခြင်းတွင် ဖျောက်ထားသည်"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"ဂြိုဟ်တုနှင့် အလိုအလျောက် ချိတ်ဆက်ထားသည်"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များကို ပို့နိုင်၊ လက်ခံနိုင်သည်"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"အလုပ်လုပ်ပုံ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ဆိုင်းငံ့ထားသည်…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> တို့ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို လက်ဗွေဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> တို့ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို လက်ဗွေဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းတို့ကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"သင့်မျက်နှာနမူနာ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို မျက်နှာဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"စနစ်ထည့်သွင်းရန်"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ယခုမလုပ်ပါ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> အတွက် နှိုးစက်"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"အသုံးပြုသူ ပြောင်းရန်"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"အသံပိတ်ရန်"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"အသံပိတ်ရန် တို့ပါ"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 456366f..e60f43f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -265,15 +265,17 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Feilrapport"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Avslutt økten"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Skjermdump"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Feilrapport"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv rapport"</string>
- <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Bruk dette alternativet i de fleste tilfeller. Da kan du spore fremgangen for rapporten, skrive inn flere detaljer om problemet samt ta skjermdumper. Noen deler som tar lang tid å behandle, blir kanskje utelatt."</string>
+ <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Bruk dette alternativet i de fleste tilfeller. Da kan du spore fremgangen for rapporten, skrive inn flere detaljer om problemet samt ta skjermbilder. Noen deler som tar lang tid å behandle, blir kanskje utelatt."</string>
<string name="bugreport_option_full_title" msgid="7681035745950045690">"Fullstendig rapport"</string>
- <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Bruk dette alternativet for minst mulig forstyrrelse på systemet når enheten din er treg eller ikke svarer, eller når du trenger alle rapportdelene. Det tas ikke noen skjermdump, og du kan ikke legge til flere detaljer."</string>
- <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Tar skjermdump for feilrapporten om # sekund.}other{Tar skjermdump for feilrapporten om # sekunder.}}"</string>
- <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"En skjermdump er tatt med feilrapporten"</string>
- <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Kunne ikke ta skjermdump med feilrapporten"</string>
+ <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Bruk dette alternativet for minst mulig forstyrrelse på systemet når enheten din er treg eller ikke svarer, eller når du trenger alle rapportdelene. Det tas ikke noen skjermbilde, og du kan ikke legge til flere detaljer."</string>
+ <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Tar skjermbilde for feilrapporten om # sekund.}other{Tar skjermbilde for feilrapporten om # sekunder.}}"</string>
+ <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"En skjermbilde er tatt med feilrapporten"</string>
+ <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Kunne ikke ta skjermbilde med feilrapporten"</string>
<string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Stillemodus"</string>
<string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"Lyden er av"</string>
<string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"Lyden er på"</string>
@@ -359,8 +361,8 @@
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Kan trykke, sveipe, klype og gjøre andre bevegelser."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Bevegelser på fingeravtrykkssensor"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan fange inn bevegelser som utføres på enhetens fingeravtrykkssensor."</string>
- <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skjermdump"</string>
- <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ikke ta en skjermdump av skjermen."</string>
+ <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skjermbilde"</string>
+ <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ikke ta et skjermbilde av skjermen."</string>
<string name="dream_preview_title" msgid="5570751491996100804">"Forhåndsvisning, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
<string name="dream_accessibility_action_click" msgid="7392398629967797805">"lukk"</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller endre statusfeltet"</string>
@@ -509,8 +511,8 @@
<string name="permdesc_recordAudio" msgid="5857246765327514062">"Denne appen kan ta opp lyd med mikrofonen mens den er i bruk."</string>
<string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ta opp lyd i bakgrunnen"</string>
<string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Denne appen kan når som helst ta opp lyd med mikrofonen."</string>
- <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"registrere skjermdumper av appvinduer"</string>
- <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Denne appen varsles hvis det tas skjermdumper mens appen er i bruk."</string>
+ <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"registrere skjermbilder av appvinduer"</string>
+ <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Denne appen varsles hvis det tas skjermbilder mens appen er i bruk."</string>
<string name="permlab_sim_communication" msgid="176788115994050692">"sende kommandoer til SIM-kortet"</string>
<string name="permdesc_sim_communication" msgid="4179799296415957960">"Lar appen sende kommandoer til SIM-kortet. Dette er veldig farlig."</string>
<string name="permlab_activityRecognition" msgid="1782303296053990884">"gjenkjenn fysisk aktivitet"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Velg for å slå av trådløs feilsøking."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testrammeverk-modus er slått på"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Tilbakestill enheten til fabrikkstandard for å slå av Testrammeverk-modus."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsollen er aktivert"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ytelsen er påvirket. Sjekk oppstartsinnlasteren for å deaktivere."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE på forsøksstadiet er aktivert"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slipp opp volumtastene. For å slå på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, trykk og hold på begge volumtastene igjen i 3 sekunder."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Velg en funksjon du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Velg en funksjon du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med to fingre):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Velg en funksjon du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med tre fingre):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"For å bytte mellom funksjoner, trykk og hold på Tilgjengelighet-knappen."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"For å bytte mellom funksjoner, sveip opp med to fingre og hold."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"For å bytte mellom funksjoner, sveip opp med tre fingre og hold."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørring"</string>
<string name="user_switched" msgid="7249833311585228097">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtale"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrerer et innkommende anrop"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Uten kategori"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoteringer"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosialt"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheter"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Anbefalinger"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Du angir viktigheten for disse varslene."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Dette er viktig på grunn av folkene som er involvert."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tilpasset appvarsel"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Velger for tilgjengelighetssnarvei på skjermen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tilgjengelighetssnarvei"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Lukk varselpanelet"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meny"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media – spill av og sett på pause"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Opp på styrepilene"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Ned på styrepilene"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Venstre på styrepilene"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Slik fungerer det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer opplåsingen med fingeravtrykk på nytt"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerte ikke skikkelig og ble slettet"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerte ikke skikkelig og ble slettet"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerte ikke skikkelig og ble slettet. Du kan konfigurere det på nytt for å låse opp telefonen med fingeravtrykket."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerte ikke skikkelig og ble slettet. Du kan konfigurere dem på nytt for å låse opp telefonen med fingeravtrykket."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansiktslåsen på nytt"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ansiktsmodellen din fungerte ikke skikkelig og ble slettet. Du kan konfigurere den på nytt for å låse opp telefonen med ansiktet."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nå"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Bytt bruker"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Kutt lyden"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Trykk for å kutte lyden"</string>
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 55c2ef4..dee6825 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"बग रिपोर्ट"</string>
<string name="global_action_logout" msgid="6093581310002476511">"सत्रको अन्त्य गर्नुहोस्"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"स्क्रिनसट"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"बग रिपोर्ट"</string>
<string name="bugreport_message" msgid="5212529146119624326">"एउटा इमेल सन्देशको रूपमा पठाउनलाई यसले तपाईँको हालैको उपकरणको अवस्थाको बारेमा सूचना जम्मा गर्ने छ। बग रिपोर्ट सुरु गरेदेखि पठाउन तयार नभएसम्म यसले केही समय लिन्छ; कृपया धैर्य गर्नुहोस्।"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"अन्तरक्रियामूलक रिपोर्ट"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वायरलेस डिबगिङ असक्षम पार्न यो विकल्प चयन गर्नुहोस्।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"परीक्षण प्याकेज मोड सक्षम पारियो"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"क्रमसम्बन्धी कन्सोल सक्षम पारियो"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"पर्फर्मेन्समा प्रभाव परेको छ। यसलाई असक्षम पार्न बुटलोडरको जाँच गर्नुहोस्।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"परीक्षणका क्रममा रहेको MTE अन गरियो"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"भोल्युम बटनहरू थिच्न छाड्नुहोस्। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन गर्न दुवै भोल्युम बटन फेरि ३ सेकेन्डसम्म थिचिराख्नुहोस्।"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तपाईंले एक्सेसिबिलिटी बटन ट्याप गर्दा प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस्:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एउटा सुविधाबाट अर्को सुविधामा जान पहुँच बटन टच एण्ड होल्ड गर्नुहोस्।"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एउटा सुविधाबाट अर्को सुविधामा जान दुईवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्।"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एउटा सुविधाबाट अर्को सुविधामा जान तीनवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्।"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"तपाईंले अर्को पटक एक्सेसिबिलिटी बटनमा ट्याप गर्दा यो सुविधा खुल्ने छ"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। २ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। ३ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string>
<string name="user_switched" msgid="7249833311585228097">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"स्विच गरेर <xliff:g id="NAME">%1$s</xliff:g> बनाइँदै..."</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"भइरहेको कल"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"आगमन कल जाँचिँदै छ"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"वर्गीकरण नगरिएको"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"प्रवर्धनहरू"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"सोसल मिडिया"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"समाचार"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"सिफारिसहरू"</string>
<string name="importance_from_user" msgid="2782756722448800447">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"एपसम्बन्धी आफ्नो रोजाइअनुसारको सूचना"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"सहज पहुँचका लागि स्क्रिनमा राखिने सर्टकट छान्ने मेनु"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"पहुँचको सर्टकट"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"सूचना कक्ष खारेज गर्नुहोस्"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"मेनु"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"मिडिया प्ले/पज"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad को माथिको बटन"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad को तलको बटन"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad को बायाँको बटन"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यसले काम गर्ने तरिका"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"विचाराधीन..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"राम्ररी काम नगरिरहेको हुनाले <xliff:g id="FINGERPRINT">%s</xliff:g> मेटाइएको छ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"राम्ररी काम नगरिरहेका हुनाले <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> मेटाइएका छन्"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ले काम गरिरहेको थिएन र त्यसलाई मेटाइयो। फिंगरप्रिन्ट प्रयोग गरी आफ्नो फोन अनलक गर्न त्यसलाई फेरि सेट अप गर्नुहोस्।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ले राम्ररी काम गरिरहेका थिएनन् र तिनलाई मेटाइयो। फिंगरप्रिन्ट प्रयोग गरी आफ्नो फोन अनलक गर्न तिनलाई फेरि सेट अप गर्नुहोस्।"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलक फेरि सेटअप गर्नुहोस्"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तपाईंको फेस मोडेलले राम्ररी काम गरिरहेको थिएन र त्यसलाई मेटाइयो। अनुहार प्रयोग गरी आफ्नो फोन अनलक गर्न फेस मोडेल फेरि सेट अप गर्नुहोस्।"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेटअप गर्नुहोस्"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अहिले होइन"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> का निम्ति अलार्म"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"प्रयोगकर्ता बदल्नुहोस्"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्युट गर्नुहोस्"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"साउन्ड म्युट गर्न ट्याप गर्नुहोस्"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b1b3060..7bb6927 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Bugrapport"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Sessie beëindigen"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Bugrapport"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Hiermee worden gegevens over de huidige status van je apparaat verzameld en als e-mail verzonden. Wanneer u een bugrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interactief rapport"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecteer deze optie om draadloze foutopsporing uit te zetten."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test harness-modus staat aan"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Reset de fabrieksinstellingen om de test harness-modus uit te zetten."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriële console staat aan"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Dit is van invloed op de prestaties. Controleer de bootloader om dit uit te zetten."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentele MTE aangezet"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Laat de volumeknoppen los. Als je <xliff:g id="SERVICE_NAME">%1$s</xliff:g> wilt aanzetten, houd je beide volumeknoppen weer 3 seconden ingedrukt."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Kies een functie om te gebruiken als je op de knop Toegankelijkheid tikt:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Kies een functie om te gebruiken met het toegankelijkheidsgebaar (met twee vingers omhoog swipen vanaf de onderkant van het scherm):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Kies een functie om te gebruiken met het toegankelijkheidsgebaar (met drie vingers omhoog swipen vanaf de onderkant van het scherm):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Tik op de knop Toegankelijkheid en houd deze vast om tussen functies te schakelen."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Swipe met twee vingers omhoog en houd vast om tussen functies te schakelen."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Swipe met drie vingers omhoog en houd vast om tussen functies te schakelen."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string>
<string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Actief gesprek"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Een inkomend gesprek screenen"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Geen categorie"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoties"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sociaal"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nieuws"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Aanbevelingen"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Je stelt het belang van deze meldingen in."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Dit is belangrijk vanwege de betrokken mensen."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Aangepaste app-melding"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Kiezer voor snelkoppeling voor toegankelijkheid op scherm"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Snelkoppeling voor toegankelijkheid"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Meldingenpaneel sluiten"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media afspelen/onderbreken"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad omhoog"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad omlaag"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad links"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privégedeelte"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Content van gevoelige meldingen verborgen"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-content verborgen voor scherm delen vanwege beveiligingsrisico\'s"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Vanwege beveiligingsrisico\'s is app-content verborgen voor scherm delen"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch verbonden met satelliet"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Je kunt berichten sturen en krijgen zonder een mobiel of wifi-netwerk"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe het werkt"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In behandeling…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ontgrendelen met vingerafdruk weer instellen"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> werkte niet goed en is verwijderd"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werkten niet goed en zijn verwijderd"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> werkte niet goed en is verwijderd. Stel deze opnieuw in om de telefoon met je vingerafdruk te ontgrendelen."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werkten niet goed en zijn verwijderd. Stel ze opnieuw in om de telefoon met je vingerafdruk te ontgrendelen."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ontgrendelen via gezichtsherkenning weer instellen"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Je gezichtsmodel werkte niet goed en is verwijderd. Stel het opnieuw in om de telefoon met je gezicht te ontgrendelen."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Instellen"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Niet nu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Wekker voor <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Gebruiker wijzigen"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Geluid uitzetten"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tik om het geluid uit te zetten"</string>
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index b56c114..1c6d191 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"ବଗ୍ ରିପୋର୍ଟ"</string>
<string name="global_action_logout" msgid="6093581310002476511">"ସେସନ୍ ଶେଷ କରନ୍ତୁ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ସ୍କ୍ରିନସଟ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"ବଗ୍ ରିପୋର୍ଟ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ଇ-ମେଲ୍ ମେସେଜ୍ ଭାବରେ ପଠାଇବାକୁ, ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ଡିଭାଇସ୍ ବିଷୟରେ ଏହା ସୂଚନା ସଂଗ୍ରହ କରିବ। ବଗ୍ ରିପୋର୍ଟ ଆରମ୍ଭ ହେବାପରଠାରୁ ଏହାକୁ ପଠାଇବା ପାଇଁ କିଛି ସମୟ ଲାଗିବ, ଦୟାକରି ଧୈର୍ଯ୍ୟ ରଖନ୍ତୁ।"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ଇଣ୍ଟରାକ୍ଟିଭ୍ ରିପୋର୍ଟ"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ୱାୟାରଲେସ୍ ଡିବଗିଂକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ସକ୍ଷମ ଅଛି"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ଅକ୍ଷମ କରିବାକୁ ଏକ ଫ୍ୟାକ୍ଟରୀ ରିସେଟ୍ କରନ୍ତୁ।"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"କ୍ରମିକ କନ୍ସୋଲ୍କୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"କାର୍ଯ୍ୟଦକ୍ଷତା ପ୍ରଭାବିତ ହୋଇଛି। ଅକ୍ଷମ କରିବା ପାଇଁ, ବୁଟ୍ଲୋଡର୍ର ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ପରୀକ୍ଷାମୂଳକ MTEକୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ଭଲ୍ୟୁମ କୀ\'ଗୁଡ଼ିକୁ ରିଲିଜ କରନ୍ତୁ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g>କୁ ଚାଲୁ କରିବା ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ କୀ\'କୁ ପୁଣି 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇ ଧରି ରଖନ୍ତୁ।"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ଆପଣ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ଟାପ୍ କରିବା ବେଳେ ଏକ ଫିଚର୍ ବ୍ୟବହାର କରିବାକୁ ବାଛନ୍ତୁ:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଏକ ଫିଚର୍ ବାଛନ୍ତୁ (ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଏକ ଫିଚର୍ ବାଛନ୍ତୁ (ତିନୋଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ।"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ, ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ।"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମେଗ୍ନିଫିକେସନ"</string>
<string name="user_switched" msgid="7249833311585228097">"ବର୍ତ୍ତମାନର ୟୁଜର୍ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ରେ ସ୍ୱିଚ କରନ୍ତୁ…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"ଚାଲିଥିବା କଲ୍"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ଏକ ଇନକମିଂ କଲକୁ ସ୍କ୍ରିନ୍ କରୁଛି"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ଅବର୍ଗୀକୃତ"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ପ୍ରଚାରଗୁଡ଼ିକ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"ସୋସିଆଲ"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ନ୍ୟୁଜ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"ସୁପାରିଶଗୁଡ଼ିକ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ପ୍ରମୁଖତା ଆପଣ ସେଟ୍ କରନ୍ତି।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"କଷ୍ଟମ୍ ଆପ୍ ବିଜ୍ଞପ୍ତି"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ଅନ୍-ସ୍କ୍ରିନ୍ ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍ ବାଛିବା ସୁବିଧା"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ବିଜ୍ଞପ୍ତି ସେଡକୁ ଖାରଜ କରନ୍ତୁ"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ମେନୁ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ମିଡିଆ ପ୍ଲେ କରନ୍ତୁ/ବିରତ କରନ୍ତୁ"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ଉପର"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ତଳ"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ବାମ"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ଏହା କିପରି କାମ କରେ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ବାକି ଅଛି…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏଗୁଡ଼ିକୁ ଡିଲିଟ କରାଯାଇଛି"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି। ଟିପଚିହ୍ନ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏହାକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏଗୁଡ଼ିକୁ ଡିଲିଟ କରାଯାଇଛି। ଆପଣଙ୍କ ଟିପଚିହ୍ନ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏଗୁଡ଼ିକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ଫେସ୍ ଅନଲକ୍ ପୁଣି ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ଆପଣଙ୍କ ଫେସ ମଡେଲ ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି। ଫେସ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏହାକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ସେଟ ଅପ କରନ୍ତୁ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>ଙ୍କ ପାଇଁ ଆଲାରାମ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ୟୁଜରଙ୍କୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ମ୍ୟୁଟ କରନ୍ତୁ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ସାଉଣ୍ଡ ମ୍ୟୁଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 72598d1..996f255 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"ਬਗ ਰਿਪੋਰਟ"</string>
<string name="global_action_logout" msgid="6093581310002476511">"ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰੋ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਵੋ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"ਬੱਗ ਰਿਪੋਰਟ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ਇਹ ਇੱਕ ਈਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੇ ਵਰਤਮਾਨ ਡੀਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਠੀ ਕਰੇਗਾ। ਬੱਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ਅੰਤਰਕਿਰਿਆਤਮਕ ਰਿਪੋਰਟ"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਬੰਦ ਕਰਨ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"ਸੀਰੀਅਲ ਕੰਸੋਲ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ਕਾਰਗੁਜ਼ਾਰੀ ਪ੍ਰਭਾਵਿਤ ਹੋਈ ਹੈ। ਬੰਦ ਕਰਨ ਲਈ, ਬੂਟਲੋਡਰ ਦੇਖੋ।"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ਪ੍ਰਯੋਗਮਈ MTE ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ ਛੱਡੋ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕਰਨ ਲਈ, ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦੁਬਾਰਾ ਦਬਾਈ ਰੱਖੋ।"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ (ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ (ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ \'ਤੇ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
<string name="user_switched" msgid="7249833311585228097">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਵਿੱਚ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"ਜਾਰੀ ਕਾਲ"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ਇਨਕਮਿੰਗ ਕਾਲ ਦੀ ਸਕ੍ਰੀਨਿੰਗ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ਗੈਰ-ਸ਼੍ਰੇਣੀਕਿਰਤ"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ਪ੍ਰਮੋਸ਼ਨ"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"ਸੋਸ਼ਲ ਐਪਾਂ"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ਖਬਰਾਂ"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"ਸਿਫ਼ਾਰਸ਼ਾਂ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ਤੁਸੀਂ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਦੀ ਮਹੱਤਤਾ ਸੈੱਟ ਕੀਤੀ।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ਇਹ ਸ਼ਾਮਲ ਲੋਕਾਂ ਦੇ ਕਾਰਨ ਮਹੱਤਵਪੂਰਨ ਹੈ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"ਵਿਉਂਤੀ ਐਪ ਸੂਚਨਾ"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲੇ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਦਾ ਚੋਣਕਾਰ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ਸੂਚਨਾ ਸ਼ੇਡ ਖਾਰਜ ਕਰੋ"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ਮੀਨੂ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ਮੀਡੀਆ ਚਲਾਓ/ਰੋਕੋ"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ਦਾ ਉੱਪਰਲਾ ਬਟਨ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ਦਾ ਹੇਠਲਾ ਬਟਨ"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ਦਾ ਖੱਬੇ ਪਾਸੇ ਵਾਲਾ ਬਟਨ"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ਵਿਚਾਰ-ਅਧੀਨ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ ਸਨ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਫਿੰਗਰਪ੍ਰਿੰਟ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਸਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ ਸੀ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਨ੍ਹਾਂ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ਤੁਹਾਡਾ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਚਿਹਰੇ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਸਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ਸੈੱਟਅੱਪ ਕਰੋ"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ਹੁਣੇ ਨਹੀਂ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> ਲਈ ਅਲਾਰਮ"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ਵਰਤੋਂਕਾਰ ਬਦਲੋ"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ਮਿਊਟ ਕਰੋ"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ਧੁਨੀ ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f19b0d0..a608fc7 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -163,7 +163,7 @@
<string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Połączono z szyfrowaną siecią <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
<string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Połączenie przy użyciu karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g> jest teraz bezpieczniejsze"</string>
<string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Połączono z niezaszyfrowaną siecią"</string>
- <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Gdy korzystasz z karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>, połączenia, wiadomości i dane są bardziej narażone na ataki"</string>
+ <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Gdy korzystasz z karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>, połączenia, SMS-y i dane są bardziej narażone na ataki"</string>
<string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Połączenia, wiadomości i dane są obecnie bardziej podatne na ataki podczas korzystania z karty SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nGdy połączenie zostanie ponownie zaszyfrowane, otrzymasz kolejne powiadomienie."</string>
<string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Ustawienia bezpieczeństwa sieci komórkowej"</string>
<string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Więcej informacji"</string>
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Zgłoś błąd"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Zakończ sesję"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Zrzut ekranu"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Zgłoś błąd"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Informacje o bieżącym stanie urządzenia zostaną zebrane i wysłane e-mailem. Przygotowanie zgłoszenia błędu do wysłania chwilę potrwa, więc zachowaj cierpliwość."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Raport interaktywny"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Wybierz, by wyłączyć debugowanie bezprzewodowe."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tryb jarzma testowego został włączony"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Przywróć ustawienia fabryczne, by wyłączyć tryb jarzma testowego."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Konsola szeregowa włączona"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Wpływa na wydajność. Aby wyłączyć, sprawdź program rozruchowy."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Włączono eksperymentalne rozszerzenie MTE"</string>
@@ -1757,12 +1763,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Zwolnij przyciski głośności. Aby włączyć usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, naciśnij i przytrzymaj oba przyciski głośności przez 3 sekundy."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Wybierz funkcję używaną po kliknięciu przycisku ułatwień dostępu:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Wybierz funkcję, której chcesz używać w przypadku gestu ułatwień dostępu (przesunięcie dwoma palcami w górę od dołu ekranu):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Wybierz funkcję, której chcesz używać w przypadku gestu ułatwień dostępu (przesunięcie trzema palcami w górę od dołu ekranu):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Aby przełączać funkcje, naciśnij i przytrzymaj przycisk ułatwień dostępu."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Aby przełączać funkcje, przesuń dwoma palcami w górę i przytrzymaj."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Aby przełączyć funkcje, przesuń trzema palcami w górę i przytrzymaj."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcja otworzy się, gdy następnym razem klikniesz przycisk ułatwień dostępu"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 2 palcami z dołu ekranu i szybko je unieś."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 3 palcami z dołu ekranu i szybko je unieś."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Powiększenie"</string>
<string name="user_switched" msgid="7249833311585228097">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1987,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trwa połączenie"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtruję połączenie przychodzące"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Bez kategorii"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocje"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Społecznościowe"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Wiadomości"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomendacje"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ustawiłeś ważność tych powiadomień."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ta wiadomość jest ważna ze względu na osoby uczestniczące w wątku."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Niestandardowe powiadomienie z aplikacji"</string>
@@ -2194,6 +2207,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Wybierz ekranowy skrót ułatwień dostępu"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Skrót ułatwień dostępu"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zamknij obszar powiadomień"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Odtwórz/wstrzymaj multimedia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad – w górę"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad – w dół"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad – w lewo"</string>
@@ -2420,12 +2435,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to działa"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Oczekiwanie…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Skonfiguruj ponownie odblokowywanie odciskiem palca"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Odcisk palca <xliff:g id="FINGERPRINT">%s</xliff:g> nie sprawdzał się dobrze i został usunięty"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Odciski palców <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nie sprawdzały się dobrze i zostały usunięte"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Odcisk palca <xliff:g id="FINGERPRINT">%s</xliff:g> nie sprawdzał się dobrze i został usunięty. Skonfiguruj go ponownie, aby odblokowywać telefon odciskiem palca."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Odciski palca <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nie sprawdzały się dobrze i zostały usunięte. Skonfiguruj je ponownie, aby odblokowywać telefon odciskiem palca."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Skonfiguruj ponownie rozpoznawanie twarzy"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Twój model twarzy nie sprawdzał się dobrze i został usunięty. Skonfiguruj go ponownie, aby odblokowywać telefon za pomocą skanu twarzy."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Skonfiguruj"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nie teraz"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm dla: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Przełącz konto"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Wycisz"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Kliknij, aby wyciszyć dźwięk"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 6bc9fe0..fa47d04 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Relatório de bug"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Finalizar sessão"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Captura de tela"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Relatório de bug"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Relatório interativo"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1756,12 +1762,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para alternar entre recursos, toque no botão de acessibilidade e mantenha-o pressionado."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para alternar entre recursos, deslize de baixo para cima na tela com dois dedos, sem soltar."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para alternar entre recursos, deslize de baixo para cima na tela com três dedos, sem soltar."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"O recurso será aberto na próxima vez que você tocar no botão de acessibilidade"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1986,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma ligação recebida"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sem classificação"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoções"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícias"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendações"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Você definiu a importância dessas notificações."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Isso é importante por causa das pessoas envolvidas."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificação personalizada do app"</string>
@@ -2193,6 +2206,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Seletor de atalho de acessibilidade na tela"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dispensar aba de notificações"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Tocar/pausar mídia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Botão direcional: para cima"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Botão direcional: para baixo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Botão direcional: para a esquerda"</string>
@@ -2412,19 +2427,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espaço privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Conteúdo de notificação sensível oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Seu modelo de rosto não estava funcionando bem e foi excluído. Configure de novo para desbloquear o smartphone com o rosto."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuração"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Trocar usuário"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para silenciar"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 5cf49fbd..8a52303 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Relatório de erros"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Terminar sessão"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Capt. ecrã"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Relatório de erro"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Relatório interativo"</string>
@@ -663,7 +665,7 @@
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moveu o dedo demasiado lentamente. Tente novamente."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Experimente outra impressão digital"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Está demasiado claro"</string>
- <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Detetou-se que o botão ligar/desligar foi premido"</string>
+ <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Detetou-se que o botão ligar/desligar foi pressionado"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Experimente ajustar"</string>
<string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Altere a posição do seu dedo ligeiramente de cada vez"</string>
<string-array name="fingerprint_acquired_vendor">
@@ -686,7 +688,7 @@
<string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Este dispositivo não tem sensor de impressões digitais."</string>
<string name="fingerprint_error_security_update_required" msgid="8440349108169661934">"Sensor temporariamente desativado"</string>
<string name="fingerprint_error_bad_calibration" msgid="6770614925736183528">"Não é possível usar o sensor de impressões digitais. Visite um fornecedor de serviços de reparação."</string>
- <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Botão ligar/desligar premido"</string>
+ <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Botão ligar/desligar pressionado"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar a impressão digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar o bloqueio de ecrã ou a impressão digital"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração sem fios."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo de estrutura de teste ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Consola de série ativada"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho é afetado. Para desativar, selecione o carregador de arranque."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1756,12 +1762,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, prima sem soltar ambas as teclas de volume novamente durante 3 segundos."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha uma funcionalidade para utilizar quando tocar no botão Acessibilidade:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha a funcionalidade a utilizar com o gesto de acessibilidade (deslize rapidamente com dois dedos para cima a partir da parte inferior do ecrã):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha a funcionalidade a utilizar com o gesto de acessibilidade (deslize rapidamente com três dedos para cima a partir da parte inferior do ecrã):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para alternar entre funcionalidades, toque sem soltar no botão Acessibilidade."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para alternar entre funcionalidades, deslize rapidamente com dois dedos para cima sem soltar."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para alternar entre funcionalidades, deslize rapidamente com três dedos para cima sem soltar."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"A funcionalidade vai ser aberta da próxima vez que tocar no botão Acessibilidade"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize com 2 dedos a partir da parte inferior do ecrã e solte rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize para cima com 3 dedos a partir da parte inferior do ecrã e solte rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
<string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
<string name="user_switching_message" msgid="1912993630661332336">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1986,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em curso"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"A filtrar uma chamada recebida…"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sem categoria"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoções"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Redes sociais"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícias"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendações"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Definiu a importância destas notificações."</string>
<string name="importance_from_person" msgid="4235804979664465383">"É importante devido às pessoas envolvidas."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificação de app personalizada"</string>
@@ -2193,6 +2206,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selecionador de atalhos de acessibilidade no ecrã"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorar o painel de notificações"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproduzir/pausar multimédia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Teclado direcional: para cima"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Teclado direcional: para baixo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Teclado direcional: para a esquerda"</string>
@@ -2419,12 +2434,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configure o Desbloqueio por impressão digital novamente"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A <xliff:g id="FINGERPRINT">%s</xliff:g> não estava a funcionar bem e foi eliminada"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"A <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam a funcionar bem e foram eliminadas"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A <xliff:g id="FINGERPRINT">%s</xliff:g> não estava a funcionar bem e foi eliminada. Configure-a novamente para desbloquear o telemóvel com a impressão digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"A <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam a funcionar bem e foram eliminadas. Configure-as novamente para desbloquear o telemóvel com a sua impressão digital."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial novamente"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"O seu modelo de rosto não estava a funcionar bem e foi eliminado. Configure-o novamente para desbloquear o telemóvel com o rosto."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme de <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Mudar de utilizador"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para desativar o som"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 6bc9fe0..fa47d04 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Relatório de bug"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Finalizar sessão"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Captura de tela"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Relatório de bug"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Relatório interativo"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1756,12 +1762,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para alternar entre recursos, toque no botão de acessibilidade e mantenha-o pressionado."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para alternar entre recursos, deslize de baixo para cima na tela com dois dedos, sem soltar."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para alternar entre recursos, deslize de baixo para cima na tela com três dedos, sem soltar."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"O recurso será aberto na próxima vez que você tocar no botão de acessibilidade"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
<string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1986,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma ligação recebida"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Sem classificação"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoções"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícias"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendações"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Você definiu a importância dessas notificações."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Isso é importante por causa das pessoas envolvidas."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificação personalizada do app"</string>
@@ -2193,6 +2206,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Seletor de atalho de acessibilidade na tela"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dispensar aba de notificações"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Tocar/pausar mídia"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Botão direcional: para cima"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Botão direcional: para baixo"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Botão direcional: para a esquerda"</string>
@@ -2412,19 +2427,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espaço privado"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Conteúdo de notificação sensível oculto"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Seu modelo de rosto não estava funcionando bem e foi excluído. Configure de novo para desbloquear o smartphone com o rosto."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuração"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Trocar usuário"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para silenciar"</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index e4a6a07..9c6f87e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Raport despre erori"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Încheie sesiunea"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Instantaneu"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Raport de eroare"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Acest raport va colecta informații despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Ai răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Raport interactiv"</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selectează pentru a dezactiva remedierea erorilor wireless."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modul Set de testare este activat"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Revino la setările din fabrică pentru a dezactiva modul Set de testare."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Consola din serie este activată"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performanța este afectată. Pentru a dezactiva, verifică programul bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimentală activată"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Eliberează butoanele de volum. Pentru a activa <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, apasă lung pe ambele butoane de volum timp de trei secunde încă o dată."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Alege o funcție pe care să o folosești când atingi butonul de accesibilitate:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Alege o funcție pe care să o folosești cu gestul de accesibilitate (glisează în sus cu două degete din partea de jos a ecranului):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Alege o funcție pe care să o folosești cu gestul de accesibilitate (glisează în sus cu trei degete din partea de jos a ecranului):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Pentru a comuta între funcții, atinge lung butonul de accesibilitate."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Pentru a comuta între funcții, glisează în sus cu două degete și ține apăsat."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pentru a comuta între funcții, glisează în sus cu trei degete și ține apăsat."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Mărire"</string>
<string name="user_switched" msgid="7249833311585228097">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Apel în desfășurare"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Se filtrează un apel primit"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Neclasificate"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoțiii"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Rețele sociale"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Știri"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomandări"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Tu setezi importanța acestor notificări."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Notificarea este importantă având în vedere persoanele implicate."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificare de aplicație personalizată"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de comenzi rapide de accesibilitate de pe ecran"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Comandă rapidă de accesibilitate"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Închide fereastra de notificări"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meniu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Redă / întrerupe conținutul media"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad sus"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad jos"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad stânga"</string>
@@ -2419,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cum funcționează"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"În așteptare..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurează din nou Deblocarea cu amprenta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu funcționa bine și a fost ștearsă"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu funcționau bine și au fost șterse"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu funcționa bine și s-a șters. Configureaz-o din nou pentru a-ți debloca telefonul cu amprenta."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu funcționau bine și s-au șters. Configurează-le din nou pentru a-ți debloca telefonul cu amprenta."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Reconfigurează Deblocarea facială"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Modelul tău facial nu funcționa bine și s-a șters. Configurează-l din nou pentru a-ți debloca telefonul folosindu-ți chipul."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurează"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nu acum"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarmă pentru <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Schimbă utilizatorul"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Dezactivează sunetul"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Atinge pentru a dezactiva sunetul"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0e98b3f..ac2e563 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Отчет об ошибке"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Закончить сеанс"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Скриншот"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Отчет об ошибке"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Информация о текущем состоянии вашего устройства будет собрана и отправлена по электронной почте. Подготовка отчета займет некоторое время."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактивный отчет"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Нажмите, чтобы отключить отладку по Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Тестовый режим включен"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Чтобы отключить тестовый режим, сбросьте настройки до заводских."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Консоль последовательного порта включена"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Производительность устройства снижена. Чтобы отключить консоль, перейдите в загрузчик операционной системы."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Включена экспериментальная функция MTE"</string>
@@ -1757,12 +1763,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" включена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" отключена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Отпустите кнопки громкости. Чтобы включить <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, нажмите и удерживайте обе кнопки регулировки громкости в течение трех секунд."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Выберите функцию, которая будет запускаться при нажатии кнопки специальных возможностей:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Выберите функцию, которая будет запускаться с помощью жеста (провести по экрану снизу вверх двумя пальцами):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Выберите функцию, которая будет запускаться с помощью жеста (провести по экрану снизу вверх тремя пальцами):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Для переключения между функциями нажмите и удерживайте кнопку специальных возможностей."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Для переключения между функциями проведите по экрану снизу вверх двумя пальцами и задержите их."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Для переключения между функциями проведите по экрану снизу вверх тремя пальцами и задержите их."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
<string name="user_switched" msgid="7249833311585228097">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Смена профиля на \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1978,6 +1990,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущий вызов"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Фильтрация входящего вызова"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Без категории"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакции"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Общение"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Новости"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рекомендации"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Вы определяете важность этих уведомлений."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Важное (люди)"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Уведомление пользовательского приложения"</string>
@@ -2194,6 +2210,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Выбор действия для быстрого включения"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Быстрое включение"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Скрыть панель уведомлений"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Воспроизведение и пауза"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad – вверх"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad – вниз"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad – влево"</string>
@@ -2413,19 +2431,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Частное пространство"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Конфиденциальная информация в уведомлении скрыта"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Содержимое приложения исключено из демонстрации экрана в целях безопасности."</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Для безопасности содержимое приложения при демонстрации экрана скрыто."</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Автоматически подключено к системам спутниковой связи"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можете отправлять и получать сообщения без доступа к мобильной сети или Wi-Fi."</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Узнать принцип работы"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Обработка…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Настройте разблокировку по отпечатку пальца заново"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Отпечаток пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" оказался неудачным и был удален."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Отпечатки пальцев \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" оказались неудачными и были удалены."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Отпечаток пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" оказался неудачным и был удален. Чтобы использовать разблокировку с помощью отпечатка пальца, настройте ее заново."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Отпечатки пальцев \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" оказались неудачными и были удалены. Чтобы использовать разблокировку с помощью отпечатка пальца, настройте ее заново."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Настройте фейсконтроль заново"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель лица оказалась неудачной и была удалена. Чтобы пользоваться фейсконтролем, настройте его заново."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настроить"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сейчас"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будильник пользователя <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Сменить пользователя"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Отключить звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Нажмите, чтобы отключить звук."</string>
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 03068fe..fd8b536 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"දෝෂ වර්තාව"</string>
<string name="global_action_logout" msgid="6093581310002476511">"සැසිය අවසන් කරන්න"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"තිර රුව"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"දෝෂ වර්තාව"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ඊ-තැපැල් පණිවිඩයක් ලෙස යැවීමට මෙය ඔබගේ වත්මන් උපාංග තත්වය ගැන තොරතුරු එකතු කරනු ඇත. දෝෂ වාර්තාව ආරම්භ කර එය යැවීමට සූදානම් කරන තෙක් එයට කිසියම් කාලයක් ගතවනු ඇත; කරුණාකර ඉවසන්න."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"අන්තර්ක්රියා වාර්."</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"නොරැහැන් නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"පුරක පරීක්ෂා ප්රකාරය සබලයි"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"පුරක පරීක්ෂා ප්රකාරය අබල කිරීමට කර්මාන්තශාලා යළි සැකසීමක් ඉටු කරන්න."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"අනුක්රමික කොන්සෝලය සබලයි"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"කාර්ය සාධනය බලපෑමට ලක් වී ඇත. අබල කිරීමට, ආරම්භකය පරීක්ෂා කරන්න."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"අත්හදා බැලීමේ MTE සබලයි"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාත්මකයි."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාවිරහිතයි."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"හඬ පරිමා යතුරු මුදා හරින්න. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> සක්රීය කිරීමට, හඬ පරිමා යතුරු දෙකම නැවත තත්පර 3ක් ඔබා අල්ලා සිටින්න."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ඔබ ප්රවේශ්යතා බොත්තම තට්ටු කරන විට භාවිත කිරීමට විශේෂාංගයක් තෝරා ගන්න:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ප්රවේශ්යතා ඉංගිතය සමඟ භාවිතයට විශේෂාංගයක් තෝරා ගන්න (ඇඟිලි දෙකකින් තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ප්රවේශ්යතා ඉංගිතය සමඟ භාවිතයට විශේෂාංගයක් තෝරා ගන්න (ඇඟිලි තුනකින් තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"විශේෂාංග අතර මාරු වීමට, ප්රවේශ්යතා බොත්තම ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"විශේෂාංග අතර මාරු වීමට, ඇඟිලි දෙකකින් ඉහළට ස්වයිප් කර අල්ලාගෙන සිටින්න."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"විශේෂාංග අතර මාරු වීමට, ඇඟිලි තුනකින් ඉහළට ස්වයිප් කර අල්ලාගෙන සිටින්න."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"විශාලනය"</string>
<string name="user_switched" msgid="7249833311585228097">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> වෙත මාරු කරමින්…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"කරගෙන යන ඇමතුම"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"එන ඇමතුමක් පරීක්ෂා කරන්න"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"වර්ගීකරණය නොකළ"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ප්රවර්ධන"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"සමාජයීය"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"පුවත්"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"නිර්දේශ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ඔබ මෙම දැනුම්දීම්වල වැදගත්කම සකසා ඇත."</string>
<string name="importance_from_person" msgid="4235804979664465383">"සම්බන්ධ වූ පුද්ගලයන් නිසා මෙය වැදගත් වේ."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"අභිරුචි යෙදුම් දැනුම් දීම"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"තිරය මත ප්රවේශ්යතා කෙටිමං තෝරනය"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ප්රවේශ්යතා කෙටිමඟ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"දැනුම්දීම් සෙවන ඉවත ලන්න"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"මෙනුව"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"මාධ්ය වාදනය/විරාමය"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ඉහළ"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad පහළ"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad වම"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"එය ක්රියා කරන ආකාරය"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"පොරොත්තුයි..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ඇඟිලි සලකුණු අගුලු හැරීම නැවත සකසන්න"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> හොඳින් ක්රියා නොකළ අතර එය මකන ලදි"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> හොඳින් ක්රියා නොකළ අතර ඒවා මකන ලදි"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> හොඳින් ක්රියා නොකළේය, එය මකන ලදි ඇඟිලි සලකුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට එය නැවත සකසන්න."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> හොඳින් ක්රියා නොකළේය, කාර්යසාධනය දියුණූ කිරීමට ඒවා මකන ලදි. ඔබේ ඇඟිලි සලකුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට ඒවා නැවත සකසන්න."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"මුහුණෙන් අගුලු හැරීම නැවත සකසන්න"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ඔබේ මුහුණු මාදිලිය හොඳින් ක්රියා නොකරයි, එය මකන ලදි. මුහුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට එය නැවත සකසන්න."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"සකසන්න"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"දැන් නොවේ"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> සඳහා එලාමය"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"පරිශීලක මාරු කරන්න"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"නිහඬ කරන්න"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ශබ්දය නිශ්ශබ්ද කිරීමට තට්ටු කරන්න"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 694c55bb..c660fbd 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Hlásenie o chybách"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Ukončiť reláciu"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snímka obrazovky"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Nahlásiť chybu"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Týmto zhromaždíte informácie o aktuálnom stave zariadenia. Informácie je potom možné odoslať e-mailom, chvíľu však potrvá, kým bude hlásenie chyby pripravené na odoslanie. Prosíme vás preto o trpezlivosť."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktívne nahlásenie"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Výberom zakážete bezdrôtové ladenie."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Režim správcu testov je aktivovaný"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Ak chcete zakázať režim správcu testov, obnovte výrobné nastavenia."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Sériová konzola je povolená"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ovplyvňuje výkon. Ak ju chcete zakázať, skontrolujte zavádzací program systému."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Je zapnuté experimentálne rozšírenie MTE"</string>
@@ -1757,12 +1763,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvoľnite tlačidlá hlasitosti. Ak chcete zapnúť službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pridržte tri sekundy obe tlačidlá hlasitosti."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Klepnutím na tlačidlo dostupnosti vyberte požadovanú funkciu:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Vyberte funkciu, ktorú chcete používať s daným gestom dostupnosti (potiahnutím dvoma prstami z dolnej časti obrazovky nahor):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Vyberte funkciu aktivovanú daným gestom dostupnosti (potiahnutím troma prstami z dolnej časti obrazovky nahor):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funkcie prepnete pridržaním tlačidla dostupnosti."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funkcie prepnete potiahnutím dvoma prstami nahor a pridržaním."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funkcie prepnete potiahnutím troma prstami nahor a pridržaním."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zväčšenie"</string>
<string name="user_switched" msgid="7249833311585228097">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1990,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Prebiehajúci hovor"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Preveruje sa prichádzajúci hovor"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizované"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promá"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sociálne siete"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Správy"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Odporúčania"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Nastavili ste dôležitosť týchto upozornení."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Táto správa je dôležitá vzhľadom na osoby, ktorých sa to týka."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Vlastné upozornenie na aplikáciu"</string>
@@ -2194,6 +2210,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Výber skratky dostupnosti na obrazovke"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Skratka dostupnosti"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zavrieť panel upozornení"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Ponuka"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Prehrať / pozastaviť médium"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Stlačiť tlačidlo nahor krížového ovládača"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Stlačiť tlačidlo nadol krížového ovládača"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Stlačiť tlačidlo doľava krížového ovládača"</string>
@@ -2413,19 +2431,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Súkromný priestor"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Obsah citlivého upozornenia je skrytý"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie bol na účely zabezpečenia skrytý v zdieľaní obrazovky"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie je z bezpečnostných dôvodov pri zdieľaní obrazovky skrytý"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky pripojené k satelitu"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"Správy môžete odosielať a prijímať bez mobilnej siete či siete Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ako to funguje"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Znova nastavte odomknutie odtlačkom prsta"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Odtlačok <xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správne a bol odstránený"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Odtlačky <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovali správne a boli odstránené"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Odtlačok <xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správne a bol odstránený. Ak chcete odomykať telefón odtlačkom prsta, nastavte ho znova."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Odtlačky <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovali správne a boli odstránené. Ak chcete odomykať telefón odtlačkom prsta, nastavte ich znova."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Znova nastavte odomknutie tvárou"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Váš model tváre nefungoval správne a bol odstránený. Ak chcete odomykať telefón tvárou, nastavte ho znova."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastaviť"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teraz nie"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Budík pre používateľa <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Prepnúť používateľa"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ignorovať"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Klepnutím vypnite zvuk"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index edf80c5..b5f9dc5 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Poročilo o napakah"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Končaj sejo"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Posnetek"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Poročilo o napakah"</string>
<string name="bugreport_message" msgid="5212529146119624326">"S tem bodo zbrani podatki o trenutnem stanju naprave, ki bodo poslani v e-poštnem sporočilu. Izvedba poročila o napakah in priprava trajata nekaj časa, zato bodite potrpežljivi."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktivno poročilo"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izberite, če želite onemogočiti brezžično odpravljanje napak."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Način preizkusnega ogrodja je omogočen"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Če želite onemogočiti način preizkusnega ogrodja, ponastavite napravo na tovarniške nastavitve."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogočena"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Učinkovitost delovanja je slabša. Uporabo konzole lahko onemogočite v zagonskem nalagalniku."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Preizkusne razširitve MTE so omogočene"</string>
@@ -1757,12 +1763,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Spustite gumba za glasnost. Če želite vklopiti storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pritisnite in 3 sekunde pridržite oba gumba za glasnost."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izberite funkcijo, ki jo želite uporabljati, ko se dotaknete gumba za dostopnost:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izberite funkcijo, ki jo želite zagnati s potezo za dostopnost (vlečenje z dvema prstoma z dna zaslona navzgor):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izberite funkcijo, ki jo želite zagnati s potezo za dostopnost (vlečenje s tremi prsti z dna zaslona navzgor):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Če želite preklopiti med funkcijami, pridržite gumb za dostopnost."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Če želite preklopiti med funkcijami, z dvema prstoma povlecite navzgor in pridržite."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Če želite preklopiti med funkcijami, s tremi prsti povlecite navzgor in pridržite."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povečava"</string>
<string name="user_switched" msgid="7249833311585228097">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Preklapljanje na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1978,6 +1990,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktivni klic"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Preverjanje dohodnega klica"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizirano"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Družbeno"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Novice"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Priporočila"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Vi določite raven pomembnosti teh obvestil."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Pomembno zaradi udeleženih ljudi."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Obvestilo po meri iz aplikacije"</string>
@@ -2194,6 +2210,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Izbirnik zaslonske bližnjice za dostopnost"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Bližnjica za dostopnost"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Opusti zaslon z obvestili"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Predvajaj/začasno zaustavi predstavnost"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Smerni gumb gor"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Smerni gumb dol"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Smerni gumb levo"</string>
@@ -2420,12 +2438,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako deluje"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"V teku …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vnovična nastavitev odklepanja s prstnim odtisom"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ni deloval pravilno in je bil izbrisan"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> in <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nista delovala pravilno in sta bila izbrisana"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ni deloval pravilno in je bil izbrisan. Znova ga nastavite, če želite telefon odklepati s prstnim odtisom."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> in <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nista delovala pravilno in sta bila izbrisana. Znova ju nastavite, če želite telefon odklepati s prstnim odtisom."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vnovična nastavitev odklepanja z obrazom"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model obraza ni deloval pravilno in je bil izbrisan. Znova ga nastavite, če želite telefon odklepati z obrazom."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavi"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne zdaj"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za uporabnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Preklop uporabnika"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Izklop zvoka"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dotaknite se za izklop zvoka"</string>
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 88c4987..35dd218 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Raport i defektit në kod"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Jepi fund sesionit"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Pamja e ekranit"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Raporti i defekteve në kod"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ky funksion mundëson mbledhjen e informacioneve mbi gjendjen aktuale të pajisjes për ta dërguar si mesazh mail-i. Do të duhet pak kohë nga nisja e raportit të defekteve në kod. Faleminderit për durimin."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Raport interaktiv"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Zgjidh për të çaktivizuar korrigjimin përmes Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modaliteti i lidhjes së testimit është aktivizuar"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Kryej një rivendosje në cilësimet e fabrikës për të çaktivizuar \"Modalitetin e lidhjes së testimit\"."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Paneli komandues i serisë është aktivizuar"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ndikohet cilësia e funksionimit. Për ta çaktivizuar, kontrollo ngarkuesin e sistemit."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"MTE eksperimentale u aktivizua"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lësho tastet e volumit. Për të aktivizuar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, shtyp dhe mbaj shtypur të dy tastet e volumit sërish për 3 sekonda."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Zgjidh një funksion për ta përdorur kur troket butonin e qasshmërisë:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Zgjidh një veçori për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me dy gishta):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Zgjidh një veçori për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me tre gishta):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Për të kaluar mes veçorive, prek dhe mbaj prekur butonin e qasshmërisë."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Për të kaluar mes veçorive, rrëshqit shpejt lart me dy gishta dhe mbaje prekur."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Për të kaluar mes veçorive, rrëshqit shpejt lart me tre gishta dhe mbaje prekur."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zmadhimi"</string>
<string name="user_switched" msgid="7249833311585228097">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"Po kalon në \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Telefonatë në vazhdim"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Po filtron një telefonatë hyrëse"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"E pakategorizuara"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promovime"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sociale"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Lajme"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomandime"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ke caktuar rëndësinë e këtyre njoftimeve."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Është i rëndësishëm për shkak të personave të përfshirë."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Njoftim i personalizuar për aplikacionin"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Zgjedhësi i shkurtores së qasshmërisë në ekran"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shkurtorja e qasshmërisë"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Hiq \"Strehën e njoftimeve\""</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyja"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Luaj/vendos në pauzë median"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Lart në bllokun e drejtimit"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Poshtë në bllokun e drejtimit"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Majtas në bllokun e drejtimit"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Si funksionon"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\""</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk po funksiononte mirë dhe u fshi"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk po funksiononin mirë dhe u fshinë"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk po funksiononte mirë dhe u fshi. Konfiguroje përsëri për ta shkyçur telefonin tënd me gjurmën e gishtit."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk po funksiononin mirë dhe u fshinë. Konfiguroji përsëri për ta shkyçur telefonin tënd me gjurmën e gishtit."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguro \"Shkyçjen me fytyrë\" përsëri"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Modeli yt i fytyrës nuk po funksiononte mirë dhe u fshi. Konfiguroje përsëri për ta shkyçur telefonin tënd me fytyrën."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfiguro"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Jo tani"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarmi për <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Ndërro përdoruesin"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Hiqi zërin"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Trokit për t\'i hequr zërin"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index f620246..a979047 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -266,6 +266,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Јави грешку"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Заврши сесију"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Снимак екрана"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Јави грешку"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Овим ће се прикупити информације о тренутном стању уређаја како би биле послате у поруци е-поште. Од започињања извештаја о грешци до тренутка за његово слање проћи ће неко време; будите стрпљиви."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактив. извештај"</string>
@@ -517,11 +519,11 @@
<string name="permlab_activityRecognition" msgid="1782303296053990884">"препознавање физичких активности"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ова апликација може да препозна физичке активности."</string>
<string name="permlab_camera" msgid="6320282492904119413">"снимање фотографија и видеа"</string>
- <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео снимке помоћу камере док се апликација користи."</string>
- <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео снимке у позадини"</string>
+ <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео помоћу камере док се апликација користи."</string>
+ <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео у позадини"</string>
<string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку."</string>
<string name="permlab_systemCamera" msgid="3642917457796210580">"Дозволите некој апликацији или услузи да приступа камерама система да би снимала слике и видео снимке"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео снимке помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером."</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ова апликација може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неке апликације)."</string>
<string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Дозволите апликацији или услузи да приступа камери као корисник система без графичког корисничког интерфејса."</string>
@@ -1412,6 +1414,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изаберите да бисте онемогућили бежично отклањање грешака."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Омогућен је режим пробног коришћења"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Серијска конзола је омогућена"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Перформансе су смањене. Да бисте онемогући конзолу, проверите покретачки програм."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментални MTE је омогућен"</string>
@@ -1756,12 +1762,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Пустите тастере за јачину звука. Да бисте укључили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, поново притисните и задржите оба тастера за јачину звука 3 секунде."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изаберите функцију која ће се користити када додирнете дугме Приступачност:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу три прста превуците нагоре од дна екрана):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Да бисте прелазили са једне функције на другу, додирните и задржите дугме Приступачност."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу два прста и задржите."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу три прста и задржите."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увећање"</string>
<string name="user_switched" msgid="7249833311585228097">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1989,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Позив је у току"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Проверава се долазни позив"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризовано"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоције"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Друштвене мреже"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Вести"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Препоруке"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ви подешавате важност ових обавештења."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Ово је важно због људи који учествују."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Прилагођено обавештење о апликацији"</string>
@@ -2193,6 +2209,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Алатка за бирање пречица за приступачност на екрану"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пречица за приступачност"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Одбаци траку са обавештењима"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Мени"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Пусти/паузирај медије"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"нагоре на D-pad-у"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"надоле на D-pad-у"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"налево на D-pad-у"</string>
@@ -2419,12 +2437,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Принцип рада"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"На чекању..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поново подесите откључавање отиском прста"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> није функционисао и избрисали смо га"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> нису функционисали и избрисали смо их"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> није функционисао и избрисали смо га. Поново га подесите да бисте телефон откључавали отиском прста."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> нису функционисали и избрисали смо их. Поново их подесите да бисте телефон откључавали отиском прста."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Поново подесите откључавање лицем"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ваш модел лица није функционисао и избрисали смо га. Поново га подесите да бисте телефон откључавали лицем."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Подеси"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сада"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Аларм за: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Промени корисника"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Искључи звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Додирните да бисте искључили звук"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 35c4c71..eac67f5 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Felrapport"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Avsluta session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Skärmbild"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Felrapport"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Nu hämtas information om aktuell status för enheten, som sedan skickas i ett e-postmeddelade. Det tar en liten stund innan felrapporten är färdig och kan skickas, så vi ber dig ha tålamod."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv rapport"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Välj för att inaktivera trådlös felsökning."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Läget för testverktyg har aktiverats"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Inaktivera testverktygsläget genom att göra en återställning till standardinställningarna."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsolen är aktiverad"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Prestandan påverkas. Inaktivera via starthanteraren."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentell MTE har aktiverats"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Släpp volymknapparna. Du kan aktivera <xliff:g id="SERVICE_NAME">%1$s</xliff:g> genom att hålla båda volymknapparna nedtryckta i tre sekunder igen."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Välj en funktion som ska användas när du trycker på tillgänglighetsknappen:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Välj en funktion som ska användas med tillgänglighetsrörelsen (svepa uppåt med två fingrar från skärmens nederkant):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Välj en funktion som ska användas med tillgänglighetsrörelsen (svepa uppåt med tre fingrar från skärmens nederkant):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Byt mellan funktionerna genom att trycka länge på tillgänglighetsknappen."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Byt funktion genom att svepa uppåt med två fingrar och hålla kvar dem."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Byt funktion genom att svepa uppåt med tre fingrar och hålla kvar dem."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Förstoring"</string>
<string name="user_switched" msgid="7249833311585228097">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtal"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Ett inkommande samtal filtreras"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Okategoriserad"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Kampanjer"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Socialt"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheter"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekommendationer"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Du anger hur viktiga aviseringarna är."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Detta är viktigt på grund av personerna som deltar."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Anpassad appavisering"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Valfunktion för tillgänglighetsgenväg på skärmen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Aktivera tillgänglighet snabbt"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Stäng meddelandepanelen"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meny"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Spela upp/pausa"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Styrkors, upp"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Styrkors, ned"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Styrkors, vänster"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Så fungerar det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Väntar …"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurera fingeravtryckslås igen"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerade inte bra och har raderats"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerade inte bra och har raderats"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerade inte bra och har raderats. Konfigurera det igen för att låsa upp telefonen med fingeravtryck."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerade inte bra och har raderats. Konfigurera dem igen för att låsa upp telefonen med fingeravtryck."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurera ansiktslås igen"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ansiktsmodellen fungerade inte bra och har raderats. Konfigurera den igen för att låsa upp telefonen med ansiktet."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ställ in"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Inte nu"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm för <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Byt användare"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ljud av"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tryck för att stänga av ljudet"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index dc19026..409603c 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Ripoti ya hitilafu"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Maliza kipindi"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Picha ya skrini"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Ripoti ya hitilafu"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Hii itakusanya maelezo kuhusu hali ya kifaa chako kwa sasa, na itume kama barua pepe. Itachukua muda mfupi tangu ripoti ya hitilafu ianze kuzalishwa hadi iwe tayari kutumwa; vumilia."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Ripoti ya kushirikiana"</string>
@@ -1318,7 +1320,7 @@
<string name="volume_call" msgid="7625321655265747433">"Sauti ya simu inayoendelea"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Sauti ya simu inayoendelea ya Bluetooth"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Sauti ya kengele"</string>
- <string name="volume_notification" msgid="6864412249031660057">"Sauti ya notisi"</string>
+ <string name="volume_notification" msgid="6864412249031660057">"Sauti ya arifa"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Kiwango"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Sauti ya Bluetooth"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"Sauti ya toni mlio"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Chagua ili uzime utatuzi usiotumia waya."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Hali ya Muunganisho wa Majaribio imewashwa"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Rejesha mipangilio iliyotoka nayo kiwandani ili uzime hali ya Muunganisho wa Majaribio."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Muunganisho kupitia mlango umewashwa"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Utendaji unaathirika. lli uzime, teua programu ya kuwasha mfumo wa uendeshaji."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Kipengele cha majaribio cha MTE kimeruhusiwa"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Achilia vitufe vya sauti. Ili uwashe <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, bonyeza na ushikilie tena vitufe vyote vya sauti kwa sekunde 3."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Chagua kipengele utakachotumia ukigusa kitufe cha ufikivu:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Chagua kipengele cha kutumia pamoja na ishara ya ufikivu (telezesha vidole viwili kutoka chini kwenda juu kwenye skrini):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Chagua kipengele cha kutumia pamoja na ishara ya ufikivu (telezesha vidole vitatu kutoka chini kwenda juu kwenye skrini):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Ili ubadilishe kati ya vipengele, gusa na ushikilie kitufe cha zana za ufikivu."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Ili ubadilishe kati ya vipengele, telezesha vidole viwili juu na ushikilie."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Ili ubadilishe kati ya vipengele, telezesha vidole vitatu juu na ushikilie."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukuzaji"</string>
<string name="user_switched" msgid="7249833311585228097">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Inaenda kwa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Simu inayoendelea"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Inachuja simu unayopigiwa"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Ambazo aina haijabainishwa"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Matoleo"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Mitandao Jamii"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Habari"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Mapendekezo"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Uliweka mipangilio ya umuhimu wa arifa hizi."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Hii ni muhimu kwa sababu ya watu waliohusika."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Arifa ya programu maalum"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Kichagua Njia ya Mkato ya Ufikivu kwenye Skrini"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Njia ya Mkato ya Ufikivu"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ondoa Sehemu ya Arifa"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Cheza/Sitisha Maudhui"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Kitufe cha juu cha Dpad"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Kitufe cha chini cha Dpad"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Kitufe cha kushoto cha Dpad"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Utaratibu wake"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Weka tena mipangilio ya Kufungua kwa Alama ya Kidole"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Alama ya <xliff:g id="FINGERPRINT">%s</xliff:g> ilikuwa na hitilafu na imefutwa"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Alama za <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> zilikuwa na hitilafu na zimefutwa"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Alama ya <xliff:g id="FINGERPRINT">%s</xliff:g> ilikuwa na hitilafu na imefutwa. Iweke tena ili ufungue simu yako kwa alama ya kidole."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Alama za <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> zilikuwa na hitilafu na zimefutwa. Ziweke tena ili ufungue simu yako kwa alama ya kidole."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Weka tena mipangilio ya Kufungua kwa Uso"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Muundo wako wa uso ulikuwa na hitilafu na umefutwa. Uweke tena ili ufungue simu yako kwa uso."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Weka mipangilio"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Si sasa"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"King\'ora cha <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Badilisha mtumiaji"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Zima sauti"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Gusa ili uzime sauti"</string>
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 91ae904..f76b2fc 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"பிழை அறிக்கை"</string>
<string name="global_action_logout" msgid="6093581310002476511">"அமர்வை முடிக்கிறது"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ஸ்கிரீன்ஷாட்"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"பிழை அறிக்கை"</string>
<string name="bugreport_message" msgid="5212529146119624326">"உங்கள் நடப்புச் சாதன நிலையை மின்னஞ்சல் செய்தியாக அனுப்ப, அது குறித்த தகவலை இது சேகரிக்கும். பிழை அறிக்கையைத் தொடங்குவதில் இருந்து, அது அனுப்புவதற்குத் தயாராகும் வரை, இதற்குச் சிறிது நேரம் ஆகும்; பொறுமையாகக் காத்திருக்கவும்."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ஊடாடத்தக்க அறிக்கை"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"வைஃபை பிழைதிருத்தத்தை முடக்க தேர்ந்தெடுக்கவும்."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"\'தன்னியக்க சோதனைப்\' பயன்முறை இயக்கப்பட்டது"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"’தன்னியக்க சோதனைப்\' பயன்முறையை முடக்க ஆரம்பநிலைக்கு மீட்டமைக்கவும்."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"சீரியல் கன்சோல் இயக்கப்பட்டது"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"செயல்திறன் பாதிக்கப்பட்டுள்ளது. முடக்குவதற்கு பூட்லோடரைத் தேர்வுசெய்யவும்."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"பரிசோதனை MTE இயக்கப்பட்டது"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆன் செய்யப்பட்டது."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆஃப் செய்யப்பட்டது."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ஒலியளவு பட்டன்களை அழுத்துவதை நிறுத்துங்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> சேவையை இயக்க, ஒலியளவு பட்டன்கள் இரண்டையும் 3 வினாடிகளுக்கு மீண்டும் அழுத்திப் பிடிக்கவும்."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"அணுகல்தன்மை பட்டனைத் தட்டுவதன் மூலம் பயன்படுத்த விரும்பும் அம்சத்தைத் தேர்ந்தெடுக்கவும்:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"அணுகல்தன்மை சைகைக்கான அம்சத்தைத் தேர்வுசெய்யவும் (இரண்டு விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"அணுகல்தன்மை சைகைக்கான அம்சத்தைத் தேர்வுசெய்யவும் (மூன்று விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"அம்சங்களுக்கு இடையே மாற அணுகல்தன்மை பட்டனைத் தொட்டுப் பிடித்திருக்கவும்."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"அம்சங்களுக்கு இடையே மாற இரண்டு விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடித்திருக்கவும்."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"அம்சங்களுக்கு இடையே மாற மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடித்திருக்கவும்."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"பெரிதாக்கல்"</string>
<string name="user_switched" msgid="7249833311585228097">"நடப்பு பயனர் <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>க்கு மாறுகிறது…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"செயலில் இருக்கும் அழைப்பு"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"உள்வரும் அழைப்பை மதிப்பாய்வு செய்கிறது"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"வகைப்படுத்தப்படாதவை"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"சலுகைகள்"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"சமூகம்"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"செய்திகள்"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"பரிந்துரைகள்"</string>
<string name="importance_from_user" msgid="2782756722448800447">"இந்த அறிவிப்புகளின் முக்கியத்துவத்தை அமைத்துள்ளீர்கள்."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ஈடுபட்டுள்ளவர்களின் காரணமாக, இது முக்கியமானது."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"பிரத்தியேக ஆப்ஸ் அறிவிப்பு"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"திரையிலுள்ள அணுகல்தன்மை ஷார்ட்கட்டிற்கான தேர்வி"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"அணுகல்தன்மை ஷார்ட்கட்"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"அறிவிப்பு விவரத்தை நிராகரி"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"மெனு"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"மீடியாவை இயக்குதல்/இடைநிறுத்துதல்"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"மேல் திசை காட்டும் பட்டன்"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"கீழ் திசை காட்டும் பட்டன்"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"இடது திசை காட்டும் பட்டன்"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"இது செயல்படும் விதம்"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"நிலுவையிலுள்ளது..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கப்பட்டது"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> மற்றும் <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அவை நீக்கப்பட்டன"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கபட்டது. கைரேகை மூலம் உங்கள் மொபைலை அன்லாக் செய்ய அதை மீண்டும் அமையுங்கள்."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> மற்றும் <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அவை நீக்கப்பட்டன. கைரேகை மூலம் உங்கள் மொபைலை அன்லாக் செய்ய அவற்றை மீண்டும் அமையுங்கள்."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"\'முகம் காட்டித் திறத்தல்\' அம்சத்தை மீண்டும் அமையுங்கள்"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"உங்கள் முகத் தோற்றப் பதிவு சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கப்பட்டது. உங்கள் முகத்தைப் பயன்படுத்தி மொபைலை அன்லாக் செய்ய அதை மீண்டும் அமையுங்கள்."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"அமை"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"இப்போது வேண்டாம்"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>க்கான அலாரம்"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"பயனரை மாற்றுங்கள்"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ஒலியடக்கு"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ஒலியடக்க தட்டவும்"</string>
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 759c6e6..63c6cfe 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"బగ్ రిపోర్ట్"</string>
<string name="global_action_logout" msgid="6093581310002476511">"సెషన్ను ముగించు"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"స్క్రీన్షాట్"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"బగ్ రిపోర్ట్"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ఇది ఈమెయిల్ మెసేజ్ రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ రిపోర్ట్ను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ప్రభావశీల రిపోర్ట్"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"వైర్లెస్ డీబగ్గింగ్ను డిజేబుల్ చేయడానికి ఎంచుకోండి."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"పరీక్ష నియంత్రణ మోడ్ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్ను అమలు చేయండి."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్లోడర్ను చెక్ చేయండి."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"ప్రయోగాత్మక MTE ఎనేబుల్ చేయబడింది"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"వాల్యూమ్ కీలను రిలీజ్ చేయండి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ను ఆన్ చేయడానికి, రెండు వాల్యూమ్ కీలను మళ్లీ 3 సెకన్ల పాటు నొక్కి పట్టుకోండి."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"యాక్సెస్ సామర్థ్య బటన్ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్ను ఎంచుకోండి:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక ఫీచర్ని ఎంచుకోండి (రెండు వేళ్లతో స్క్రీన్ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక ఫీచర్ను ఎంచుకోండి (మూడు చేతి వేళ్లతో స్క్రీన్ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ఫీచర్ల మధ్య మారడానికి, యాక్సెసిబిలిటీ బటన్ను నొక్కి & పట్టుకోండి."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ఫీచర్ల మధ్య మారడానికి, రెండు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ఫీచర్ల మధ్య మారడానికి, మూడు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"తర్వాతిసారి మీరు యాక్సెసిబిలిటీ బటన్ను ట్యాప్ చేసినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"తర్వాతిసారి మీరు ఈ షార్ట్కట్ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 2 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"తర్వాతిసారి మీరు ఈ షార్ట్కట్ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 3 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"మ్యాగ్నిఫికేషన్"</string>
<string name="user_switched" msgid="7249833311585228097">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> యూజర్కు స్విచ్ అవుతోంది…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"కాల్ కొనసాగుతోంది"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"ఇన్కమింగ్ కాల్ను స్క్రీన్ చేయండి"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"వర్గీకరించబడలేదు"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ప్రమోషన్లు"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"సామాజికం"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"వార్తలు"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"సిఫార్సులు"</string>
<string name="importance_from_user" msgid="2782756722448800447">"మీరు ఈ నోటిఫికేషన్ల ప్రాముఖ్యతను సెట్ చేశారు."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ఇందులో పేర్కొనబడిన వ్యక్తులను బట్టి ఇది చాలా ముఖ్యమైనది."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"అనుకూల యాప్ నోటిఫికేషన్"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"స్క్రీన్పై ఉండే యాక్సెసిబిలిటీ షార్ట్కట్ల ఎంపిక సాధనం"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"యాక్సెసిబిలిటీ షార్ట్కట్"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"నోటిఫికేషన్ తెరను తీసివేయండి"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"మెనూ"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"మీడియాను ప్లే/పాజ్ చేయండి"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad పైకి"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad కింద"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ఎడమవైపున"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ఇది ఎలా పని చేస్తుంది"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"పెండింగ్లో ఉంది..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్లాక్ను మళ్లీ సెటప్ చేయండి"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> సరిగ్గా పని చేయడం లేదు, తొలగించబడింది"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> బాగా పని చేయడం లేదు, తొలగించబడ్డాయి"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> సరిగ్గా పని చేయడం లేదు, తొలగించబడింది. వేలిముద్రతో మీ ఫోన్ను అన్లాక్ చేయడానికి దాన్ని మళ్లీ సెటప్ చేయండి."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> బాగా పని చేయడం లేదు, తొలగించబడ్డాయి. మీ వేలిముద్రతో మీ ఫోన్ను అన్లాక్ చేయడానికి వాటిని మళ్లీ సెటప్ చేయండి."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ఫేస్ అన్లాక్ను మళ్లీ సెటప్ చేయండి"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"మీ ఫేస్ మోడల్ సరిగ్గా పని చేయడం లేదు, తొలగించబడింది. ఫేస్తో మీ ఫోన్ను అన్లాక్ చేయడానికి దాన్ని మళ్లీ సెటప్ చేయండి."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"సెటప్ చేయండి"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ఇప్పుడు కాదు"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> కోసం అలారం"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"యూజర్ను మార్చండి"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"మ్యూట్ చేయండి"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"సౌండ్ను మ్యూట్ చేయడానికి ట్యాప్ చేయండి"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 282f66e..9d244ee 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"รายงานข้อบกพร่อง"</string>
<string name="global_action_logout" msgid="6093581310002476511">"จบเซสชัน"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ภาพหน้าจอ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"รายงานข้อบกพร่อง"</string>
<string name="bugreport_message" msgid="5212529146119624326">"การดำเนินการนี้จะรวบรวมข้อมูลเกี่ยวกับสถานะปัจจุบันของอุปกรณ์ของคุณ โดยจะส่งไปในรูปแบบข้อความอีเมล อาจใช้เวลาสักครู่ตั้งแต่เริ่มการสร้างรายงานข้อบกพร่องจนกระทั่งเสร็จสมบูรณ์ โปรดอดทนรอ"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"รายงานแบบอินเทอร์แอกทีฟ"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"เลือกเพื่อปิดใช้การแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"โหมดโปรแกรมทดสอบอัตโนมัติเปิดใช้อยู่"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อปิดใช้โหมดโปรแกรมทดสอบอัตโนมัติ"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"เปิดใช้คอนโซลการเรียงอันดับแล้ว"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"ประสิทธิภาพได้รับผลกระทบ ตรวจสอบ Bootloader เพื่อปิดใช้งาน"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"เปิดใช้ MTE เชิงทดสอบอยู่"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ปล่อยปุ่มปรับระดับเสียง หากต้องการเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ให้กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้อีกครั้งเป็นเวลา 3 วินาที"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่มการช่วยเหลือพิเศษดังต่อไปนี้"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"เลือกฟีเจอร์ที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 2 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ) ดังต่อไปนี้"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"เลือกฟีเจอร์ที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 3 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ) ดังต่อไปนี้"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"หากต้องการสลับระหว่างฟีเจอร์ต่างๆ ให้แตะปุ่มการช่วยเหลือพิเศษค้างไว้"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"หากต้องการสลับระหว่างฟีเจอร์ต่างๆ ให้ใช้ 2 นิ้วเลื่อนขึ้นแล้วค้างไว้"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"หากต้องการสลับระหว่างฟีเจอร์ต่างๆ ให้ใช้ 3 นิ้วเลื่อนขึ้นแล้วค้างไว้"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"การขยาย"</string>
<string name="user_switched" msgid="7249833311585228097">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="1912993630661332336">"กำลังเปลี่ยนเป็น<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"สายที่สนทนาอยู่"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"กำลังสกรีนสายเรียกเข้า"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"ไม่จัดอยู่ในหมวดหมู่ใดๆ"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"โปรโมชัน"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"โซเชียล"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"ข่าว"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"การแนะนำ"</string>
<string name="importance_from_user" msgid="2782756722448800447">"คุณตั้งค่าความสำคัญของการแจ้งเตือนเหล่านี้"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ข้อความนี้สำคัญเนื่องจากบุคคลที่เกี่ยวข้อง"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"การแจ้งเตือนที่กำหนดเองของแอป"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ตัวเลือกทางลัดการช่วยเหลือพิเศษบนหน้าจอ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ทางลัดการช่วยเหลือพิเศษ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ปิดหน้าต่างแจ้งเตือน"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"เมนู"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"เล่น/หยุดสื่อชั่วคราว"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ขึ้น"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ลง"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ซ้าย"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"พื้นที่ส่วนตัว"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"เนื้อหาการแจ้งเตือนที่ละเอียดอ่อนซ่อนอยู่"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอเพื่อความปลอดภัย"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอแล้วเพื่อความปลอดภัย"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"เชื่อมต่อกับดาวเทียมโดยอัตโนมัติ"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"คุณรับส่งข้อความผ่านดาวเทียมได้โดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"วิธีการทำงาน"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"รอดำเนินการ..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>ทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยลายนิ้วมือ"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยลายนิ้วมือ"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"ตั้งค่าการปลดล็อกด้วยใบหน้าอีกครั้ง"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"รูปแบบใบหน้าของคุณทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยใบหน้า"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ตั้งค่า"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ไว้ทีหลัง"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"นาฬิกาปลุกสำหรับ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"สลับผู้ใช้"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ปิดเสียง"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"แตะเพื่อปิดเสียง"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 31b81aa..bcb70bf 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Ulat sa bug"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Tapusin ang session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Screenshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Ulat ng bug"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Mangongolekta ito ng impormasyon tungkol sa kasalukuyang katayuan ng iyong device, na ipapadala bilang mensaheng e-mail. Gugugol ito ng kaunting oras mula sa pagsisimula ng ulat sa bug hanggang sa handa na itong maipadala; mangyaring magpasensya."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interactive na ulat"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Piliin para i-disable ang wireless na pag-debug."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Naka-enable ang Test Harness Mode"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Mag-factory reset para i-disable ang Test Harness Mode."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Naka-enable ang serial console"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Naaapektuhan ang performance. Para i-disable, lagyan ng check ang bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Na-enable ang Pang-eksperimentong MTE"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Bitawan ang mga volume key. Para i-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, muling pindutin nang matagal ang dalawang volume key sa loob ng 3 segundo."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pumili ng feature na gagana sa pamamagitan ng pag-tap mo sa button ng accessibility:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang dalawang daliri):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang tatlong daliri):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para magpalipat-lipat sa mga feature, pindutin nang matagal ang button ng accessibility."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para magpalipat-lipat sa mga feature, mag-swipe pataas gamit ang dalawang daliri at i-hold ito."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para magpalipat-lipat sa mga feature, mag-swipe pataas gamit ang tatlong daliri at i-hold ito."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pag-magnify"</string>
<string name="user_switched" msgid="7249833311585228097">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Kasalukuyang tawag"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Nagsi-screen ng papasok na tawag"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Di-nakategorya"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Mga Promosyon"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Balita"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Mga Rekomendasyon"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ikaw ang magtatakda sa kahalagahan ng mga notification na ito."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Mahalaga ito dahil sa mga taong kasangkot."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom na notification ng app"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Tagapili ng Shortcut ng Accessibility sa Screen"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shortcut ng Accessibility"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"I-dismiss ang Notification Shade"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"I-Play/I-Pause ang Media"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Up"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Down"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Left"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Paano ito gumagana"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nakabinbin..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"I-set up ulit ang Pag-unlock Gamit ang Fingerprint"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT">%s</xliff:g> at na-delete ito"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> at na-delete ang mga ito"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT">%s</xliff:g> at na-delete na ito. I-set up ulit ito para ma-unlock ang iyong telepono sa pamamagitan ng fingerprint."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> at na-delete na ang mga ito. I-set up ulit ang mga ito para ma-unlock ang iyong telepono gamit ang fingerprint mo."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"I-set up ulit ang Pag-unlock Gamit ang Mukha"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Hindi gumagana nang maayos ang iyong face model at na-delete na ito. I-set up ulit ito para ma-unlock ang iyong telepono sa pamamagitan ng mukha."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"I-set up"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Huwag muna"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm para kay <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Magpalit ng user"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"I-mute"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"I-tap para i-mute ang tunog"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 13f7c2f..03863c5 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Hata raporu"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Oturumu sonlandır"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Ekran görüntüsü"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Hata raporu"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Bu rapor, e-posta iletisi olarak göndermek üzere cihazınızın şu anki durumuyla ilgili bilgi toplar. Hata raporu başlatıldıktan sonra hazır olması biraz zaman alabilir, lütfen sabırlı olun."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Etkileşimli rapor"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Kablosuz hata ayıklamayı devre dışı bırakmak için seçin."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Bandı Modu etkin"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Test Bandı Modu\'nu devre dışı bırakmak için cihazı fabrika ayarlarına sıfırlayın."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Seri konsol etkinleştirildi"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Performans etkilendi. Devre dışı bırakmak için bootloader\'ı kontrol edin."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Deneysel MTE etkinleştirildi"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ses seviyesi tuşlarını bırakın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini etkinleştirmek için her iki ses seviyesi tuşuna yeniden basıp 3 saniye boyunca basılı tutun."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak için bir özellik seçin:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Erişilebilirlik hareketiyle (iki parmakla ekranın altından yukarı kaydırma) kullanılacak bir özellik seçin:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Erişilebilirlik hareketiyle (üç parmakla ekranın altından yukarı kaydırma) kullanılacak bir özellik seçin:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Özellikler arasında geçiş yapmak için erişilebilirlik düğmesine dokunup basılı tutun."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Özellikler arasında geçiş yapmak için iki parmakla yukarı kaydırıp basılı tutun."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Özellikler arasında geçiş yapmak için üç parmakla yukarı kaydırıp basılı tutun."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Büyütme"</string>
<string name="user_switched" msgid="7249833311585228097">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Devam eden arama"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Gelen arama süzülüyor"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Kategorize edilmemiş"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosyonlar"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Sosyal"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Haberler"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Öneriler"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Bu bildirimlerin önem derecesini ayarladınız."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Bu, dahil olan kişiler nedeniyle önemlidir."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Özel uygulama bildirimi"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekran Erişilebilirlik Kısayol Seçici"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Erişilebilirlik Kısayolu"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Bildirim Gölgesini Kapat"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Medyayı Oynat/Duraklat"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Yukarı"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Aşağı"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Sol"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"İşleyiş şekli"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Parmak İzi Kilidi\'ni tekrar kurun"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> iyi çalışmadığı için silindi"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> iyi çalışmadığı için silindi"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> iyi çalışmadığı için silindi. Telefonunuzun kilidini parmak iziyle açmak için tekrar kurun."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> iyi çalışmadığı için silindi. Telefonunuzun kilidini parmak izinizle açmak için tekrar kurun."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Yüz Tanıma Kilidi\'ni tekrar kurun"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Yüz modeliniz iyi çalışmadığı için silindi. Telefonunuzun kilidini yüzünüzle açmak için tekrar kurun."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarla"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Şimdi değil"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> için alarm"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Kullanıcı değiştir"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Sesi kapat"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Sesi kapat düğmesine dokunun"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index b8764e7..7ffd66a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -158,7 +158,7 @@
<string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Безпека мобільної мережі"</string>
<string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Шифрування, сповіщення для незашифрованих мереж"</string>
<string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Отримано доступ до ідентифікатора пристрою"</string>
- <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"О <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> у мережі поблизу зафіксовано унікальний ідентифікатор вашого пристрою (IMSI або IMEI) під час використання вашої SIM-карти <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
+ <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"О <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, коли ви використали SIM-карту <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>, мережа поблизу зафіксувала унікальний ідентифікатор вашого пристрою (IMSI або IMEI)"</string>
<string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"О <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> у мережі поблизу зафіксовано унікальний ідентифікатор вашого пристрою (IMSI або IMEI) під час використання вашої SIM-карти <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nЦе означає, що було зареєстровано ваше місцезнаходження, дії чи особу. Це звичайна практика, але може виявитися проблемою для людей, для яких важлива конфіденційність."</string>
<string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Підключено до зашифрованої мережі <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
<string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Тепер з’єднання SIM-карти <xliff:g id="NETWORK_NAME">%1$s</xliff:g> краще захищене"</string>
@@ -267,6 +267,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Звіт про помилки"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Завершити сеанс"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Знімок екрана"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Звіт про помилку"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Інформація про поточний стан вашого пристрою буде зібрана й надіслана електронною поштою. Підготовка звіту триватиме певний час."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Інтерактивний звіт"</string>
@@ -1413,6 +1415,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Натисніть, щоб вимкнути налагодження."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Увімкнено режим автоматизованого тестування"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Послідовну консоль увімкнено"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Продуктивність зазнала впливу. Щоб вимкнути, перевірте завантажувач операційної системи."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментальний запуск з MTE ввімкнено"</string>
@@ -1757,12 +1763,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> увімкнено."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> вимкнено."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Відпустіть клавіші гучності. Щоб увімкнути сервіс <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натисніть і втримуйте обидві клавіші гучності протягом 3 секунд."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Виберіть функцію для кнопки спеціальних можливостей:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Виберіть функцію для жесту спеціальних можливостей (проведення двома пальцями знизу вгору):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Виберіть функцію для жесту спеціальних можливостей (проведення трьома пальцями знизу вгору):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Щоб переключитися між функціями, натисніть і утримуйте кнопку спеціальних можливостей."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Щоб переключитися між функціями, проведіть по екрану знизу вгору двома пальцями й утримуйте їх."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Щоб переключитися між функціями, проведіть по екрану знизу вгору трьома пальцями й утримуйте їх."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Збільшення"</string>
<string name="user_switched" msgid="7249833311585228097">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Перехід у режим \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1978,6 +1990,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Активний виклик"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Вхідний виклик (Фільтр)"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Без категорії"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакції"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Соцмережі"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Новини"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рекомендації"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Ви вказуєте пріоритет цих сповіщень."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Важливе з огляду на учасників."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Користувацьке сповіщення додатка"</string>
@@ -2194,6 +2210,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Вибір екранного засобу спеціальних можливостей"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Засіб спеціальних можливостей"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрити панель сповіщень"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Відтворити/призупинити медіаконтент"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Кнопка \"вгору\" панелі керування"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Кнопка \"вниз\" панелі керування"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Кнопка \"вліво\" панелі керування"</string>
@@ -2420,12 +2438,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як це працює"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Обробка…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Налаштуйте розблокування відбитком пальця повторно"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Відбиток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" працював неналежним чином, і його видалено"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Відбитки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" працювали неналежним чином, і їх видалено"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Відбиток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" працював неналежним чином, і його видалено. Налаштуйте його ще раз, щоб розблоковувати телефон за допомогою відбитка пальця."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Відбитки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" працювали неналежним чином, і їх видалено. Налаштуйте їх ще раз, щоб розблоковувати телефон за допомогою відбитка пальця."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Налаштуйте фейс-контроль повторно"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель обличчя працювала неналежним чином, і її видалено. Налаштуйте її ще раз, щоб розблоковувати телефон за допомогою фейс-контролю."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Налаштувати"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будильник користувача <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Змінити користувача"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Вимкнути звук"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Натисніть, щоб вимкнути звук"</string>
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 1ae5e20..1b14e67 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"بگ کی اطلاع"</string>
<string name="global_action_logout" msgid="6093581310002476511">"سیشن ختم کریں"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"اسکرین شاٹ"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"بگ رپورٹ"</string>
<string name="bugreport_message" msgid="5212529146119624326">"ایک ای میل پیغام کے بطور بھیجنے کیلئے، یہ آپ کے موجودہ آلہ کی حالت کے بارے میں معلومات جمع کرے گا۔ بگ کی اطلاع شروع کرنے سے لے کر بھیجنے کیلئے تیار ہونے تک اس میں تھوڑا وقت لگے گا؛ براہ کرم تحمل سے کام لیں۔"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"متعامل رپورٹ"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"وائرلیس ڈیبگنگ کو غیر فعال کرنے کے ليے منتخب کریں۔"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ٹیسٹ ہارنیس موڈ فعال ہے"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"شمار کونسول فعال ہے"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"کارکردگی پر اثر پڑا ہے۔ غیر فعال کرنے کے ليے، بوٹ لوڈر چیک کریں۔"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"تجرباتی MTE کو فعال کیا گیا"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"والیوم کی کلیدوں کو ریلیز کریں <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کرنے کے لیے، والیوم کی دونوں کلیدوں کو دوبارہ 3 سیکنڈ تک چھوئیں اور دبائے رکھیں۔"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک خصوصیت منتخب کریں:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک خصوصیت چنیں (دو انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک خصوصیت چنیں (تین انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"خصوصیات کے مابین سوئچ کرنے کے لیے، ایکسیسبیلٹی بٹن کو ٹچ کریں اور دبائے رکھیں۔"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"خصوصیات کے مابین سوئچ کرنے کے لیے، دو انگلیوں سے اوپر سوائپ کریں اور دبائیں رکھیں۔"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"خصوصیات کے مابین سوئچ کرنے کے لیے، تین انگلیوں سے اوپر سوائپ کریں اور دبائیں رکھیں۔"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"میگنیفکیشن"</string>
<string name="user_switched" msgid="7249833311585228097">"موجودہ صارف <xliff:g id="NAME">%1$s</xliff:g>۔"</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> پر سوئچ کیا جا رہا ہے…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"جاری کال"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"اِن کمنگ کال کی اسکریننگ"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"غیر زمرہ بند"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"پروموشنز"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"سوشل"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"خبریں"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"تجاویز"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ان اطلاعات کی اہمیت آپ مقرر کرتے ہیں۔"</string>
<string name="importance_from_person" msgid="4235804979664465383">"اس میں موجود لوگوں کی وجہ سے یہ اہم ہے۔"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"حسب ضرورت ایپ کی اطلاع"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"آن اسکرین ایکسیسبیلٹی شارٹ کٹ منتخب کنندہ"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ایکسیسبیلٹی کا شارٹ کٹ"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"اطلاعاتی شیڈ برخاست کریں"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"مینیو"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"میڈیا چلائیں/موقوف کریں"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad اوپر کریں"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad نیچے کریں"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad بائیں کریں"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"اس کے کام کرنے کا طریقہ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"زیر التواء..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> اچھی طرح کام نہیں کر رہے تھے اور انہیں حذف کر دیا گیا تھا"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا۔ اپنے فون کو فنگر پرنٹ سے غیر مقفل کرنے کے لیے، اسے دوبارہ سیٹ اپ کریں۔"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> اچھی طرح کام نہیں کر رہے تھے اور انہیں حذف کر دیا گیا تھا۔ اپنے فون کو اپنے فنگر پرنٹ سے غیر مقفل کرنے کے لیے انہیں دوبارہ سیٹ اپ کریں۔"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"فیس اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"آپ کے چہرے کا ماڈل اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا۔ اپنے فون کو چہرے سے غیر مقفل کرنے کے لیے، اسے دوبارہ سیٹ اپ کریں۔"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"سیٹ اپ کریں"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ابھی نہیں"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> کیلئے الارم"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"صارف سوئچ کریں"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"خاموش کریں"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"آواز کو خاموش کرنے کے لیے تھپتھپائیں"</string>
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 8d6e169..1c8879e 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Xatoliklar hisoboti"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Seansni yakunlash"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Skrinshot"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Xatoliklar hisoboti"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Qurilmangiz holati haqidagi ma’lumotlar to‘planib, e-pochta orqali yuboriladi. Hisobotni tayyorlash biroz vaqt olishi mumkin."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv hisobot"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Uni faolsizlantirish uchun bosing."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Xavfsizlik sinovi rejimi yoqildi"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Ketma-ket port konsoli yoqildi"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Qurilma samaradorligi pasaydi. Konsolni faolsizlantirish uchun operatsion tizim yuklagichini oching."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Tajribaviy MTE yoqildi"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Tovush tugmalarini qoʻyib yuboring. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatini yoqish uchun ikkala tovush tugmasini 3 soniya bosib turing."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Qulayliklar tugmasi bosilganda ishga tushadigan funksiyani tanlang:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Qulayliklar ishorasi bilan ishga tushadigan funksiyani tanlang (ikkita barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Qulayliklar ishorasi bilan ishga tushadigan funksiyani tanlang (uchta barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funksiyalarni almashtirish uchun maxsus imkoniyatlar tugmasini bosib turing."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funksiyalarni almashtirish uchun ikkita barmoq bilan tepaga suring va ushlab turing."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funksiyalarni almashtirish uchun uchta barmoq bilan tepaga suring va ushlab turing."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Keyingi safar qulayliklar tugmasini bosganingizda funksiya ochiladi"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 2 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 3 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Kattalashtirish"</string>
<string name="user_switched" msgid="7249833311585228097">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Bunga almashilmoqda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Joriy chaqiruv"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Kiruvchi chaqiruvni filtrlash"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Turkumlanmagan"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoaksiyalar"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Ijtimoiy"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Yangiliklar"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tavsiyalar"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Siz ushbu bildirishnomalarning muhimligini belgilagansiz."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Bu odamlar siz uchun muhim."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Maxsus ilova bildirishnomasi"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda tezkor ishga tushirishni tanlagich"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tezkor ishga tushirish"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Eslatma soyasini yopish"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media ijro/pauza"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad – tepaga"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad – pastga"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad – chapga"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ishlash tartibi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Kutilmoqda..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmoq izi bilan ochish funksiyasini qayta sozlang"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi."</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi. Telefonni barmoq izi bilan ochish uchun uni qayta sozlang."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi. Telefonni barmoq izi bilan ochish uchun ularni qayta sozlang."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Yuz bilan ochishni qayta sozlash"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Yuzingiz mobeli yaxshi ishlamadi va oʻchirib tashlandi. Telefonni yuz bilan ochish uchun uni qayta sozlang."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sozlash"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hozir emas"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> uchun signal"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Foydalanuvchini almashtirish"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ovozsiz qilish"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tovushsiz qilish uchun bosing"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 857a095..5d8597e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Báo cáo lỗi"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Kết thúc phiên"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Chụp màn hình"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Báo cáo lỗi"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Báo cáo này sẽ thu thập thông tin về tình trạng thiết bị hiện tại của bạn, để gửi dưới dạng thông báo qua email. Sẽ mất một chút thời gian kể từ khi bắt đầu báo cáo lỗi cho tới khi báo cáo sẵn sàng để gửi; xin vui lòng kiên nhẫn."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Báo cáo tương tác"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Chọn để tắt tính năng gỡ lỗi qua Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Đã bật Chế độ khai thác kiểm thử"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"Đã bật bảng điều khiển cổng nối tiếp"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Hiệu suất sẽ bị ảnh hưởng. Để tắt, hãy chọn trình tải khởi động."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"Đã bật MTE thử nghiệm"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Thả phím âm lượng. Để bật <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, hãy nhấn và giữ cả 2 phím âm lượng trong 3 giây một lần nữa."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Chọn một tính năng để dùng khi bạn nhấn nút hỗ trợ tiếp cận:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Chọn một tính năng để dùng với cử chỉ hỗ trợ tiếp cận (dùng 2 ngón tay vuốt lên từ cuối màn hình):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Chọn một tính năng để dùng với cử chỉ hỗ trợ tiếp cận (dùng 3 ngón tay vuốt lên từ cuối màn hình):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Để chuyển đổi giữa các tính năng, hãy chạm và giữ nút hỗ trợ tiếp cận."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Để chuyển đổi giữa các tính năng, hãy dùng 2 ngón tay vuốt lên và giữ."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Để chuyển đổi giữa các tính năng, hãy dùng 3 ngón tay vuốt lên và giữ."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Phóng to"</string>
<string name="user_switched" msgid="7249833311585228097">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Cuộc gọi đang thực hiện"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Đang sàng lọc cuộc gọi đến"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Chưa được phân loại"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Khuyến mãi"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Mạng xã hội"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Tin tức"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Đề xuất"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Bạn đặt tầm quan trọng của các thông báo này."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Thông báo này quan trọng vì những người có liên quan."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Thông báo tùy chỉnh cho ứng dụng"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Bộ chọn lối tắt hỗ trợ tiếp cận trên màn hình"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Lối tắt hỗ trợ tiếp cận"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Đóng Ngăn thông báo"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Trình đơn"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Phát/Tạm dừng nội dung nghe nhìn"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Chuyển lên trên bằng bàn phím di chuyển"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Chuyển xuống dưới bằng bàn phím di chuyển"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Chuyển sang trái bằng bàn phím di chuyển"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cách hoạt động"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Đang chờ xử lý..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Thiết lập lại tính năng Mở khoá bằng vân tay"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> không dùng được và đã bị xoá"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> không dùng được và đã bị xoá"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng vân tay."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng vân tay."</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Thiết lập lại tính năng Mở khoá bằng khuôn mặt"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Mẫu khuôn mặt của bạn không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng khuôn mặt."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Thiết lập"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Để sau"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Chuông báo cho <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Chuyển đổi người dùng"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Tắt tiếng"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Nhấn để tắt tiếng"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6cd89cf..a9a3105 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"错误报告"</string>
<string name="global_action_logout" msgid="6093581310002476511">"结束会话"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"屏幕截图"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"错误报告"</string>
<string name="bugreport_message" msgid="5212529146119624326">"这会收集有关当前设备状态的信息,并以电子邮件的形式进行发送。从开始生成错误报告到准备好发送需要一点时间,请耐心等待。"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"互动式报告"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"选择即可停用无线调试功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"自动化测试框架模式已启用"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"恢复出厂设置以停用自动化测试框架模式。"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"已启用序列控制台"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"性能受到影响。要停用,请查看引导加载程序。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"已启用实验性 MTE"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"松开音量键。如要启用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,请再次同时按住两个音量键 3 秒。"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"选择点按“无障碍”按钮后要使用的功能:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"选择要搭配无障碍手势(用两根手指从屏幕底部向上滑动)使用的功能:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"选择要搭配无障碍手势(用三根手指从屏幕底部向上滑动)使用的功能:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"轻触并按住“无障碍”按钮,即可在多项功能之间切换。"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"用两根手指向上滑动并按住,即可在多项功能之间切换。"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"用三根手指向上滑动并按住,即可在多项功能之间切换。"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大功能"</string>
<string name="user_switched" msgid="7249833311585228097">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"正在通话"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"正在过滤来电"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"未分类"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"促销"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"社交"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"资讯"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"建议"</string>
<string name="importance_from_user" msgid="2782756722448800447">"这些通知的重要程度由您来设置。"</string>
<string name="importance_from_person" msgid="4235804979664465383">"这条通知涉及特定的人,因此被归为重要通知。"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"自定义应用通知"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"屏幕上的无障碍功能快捷方式选择器"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"无障碍功能快捷方式"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"关闭通知栏"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"菜单"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒体播放/暂停"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"向上方向键"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"向下方向键"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"向左方向键"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"私密空间"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"已隐藏敏感通知内容"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见而在屏幕共享画面中处于隐藏状态的应用内容"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见,屏幕共享画面已隐藏此应用的内容"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"自动连接到卫星"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"您无需使用移动网络或 WLAN 网络便能收发消息"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"运作方式"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待归档…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新设置指纹解锁功能"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"“<xliff:g id="FINGERPRINT">%s</xliff:g>”无法正常使用,已被删除"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"“<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>”和“<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>”无法正常使用,已被删除"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"“<xliff:g id="FINGERPRINT">%s</xliff:g>”无法正常使用,系统已将其删除。如要通过指纹解锁功能来解锁手机,请重新设置。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"“<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>”和“<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>”无法正常使用,系统已将它们删除。如要通过指纹解锁功能来解锁手机,请重新设置。"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新设置“人脸解锁”功能"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"您的脸部模型无法正常使用,系统已将其删除。如要通过人脸解锁功能来解锁手机,请重新设置。"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"设置"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"以后再说"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的闹钟"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切换用户"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"静音"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"点按即可设为静音"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 5224753..72e8308 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"錯誤報告"</string>
<string name="global_action_logout" msgid="6093581310002476511">"結束工作階段"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"螢幕截圖"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"錯誤報告"</string>
<string name="bugreport_message" msgid="5212529146119624326">"這會收集你目前裝置狀態的相關資訊,並以電郵傳送給你。從開始建立錯誤報告到準備傳送需要一段時間,請耐心等候。"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"互動報告"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"選取即可停用無線偵錯功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"已啟用測試工具模式"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"請將裝置回復原廠設定,以停用測試工具模式。"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"已啟用序列控制器"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"效能受到影響,勾選啟動程式即可停用。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"實驗版 MTE 已啟用"</string>
@@ -1755,12 +1761,15 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已開啟。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已關閉。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"鬆開音量鍵。如果要開 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時㩒住兩個音量鍵 3 秒。"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"請選擇輕按「無障礙功能」按鈕時使用的功能:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"請選擇要配搭無障礙手勢 (使用兩隻手指從螢幕底部向上滑動) 使用的功能:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"請選擇要配搭無障礙手勢 (使用三隻手指從螢幕底部向上滑動) 使用的功能:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"如要在功能之間切換,請按住無障礙功能按鈕。"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"如要在功能之間切換,請使用兩隻手指向上滑動並按住。"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"如要在功能之間切換,請使用三隻手指向上滑動並按住。"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"下次輕按無障礙功能按鈕時,就會開啟此功能"</string>
+ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快速鍵時,就會開啟此功能。請用 2 隻手指從螢幕底部向上滑動並快速放開。"</string>
+ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快速鍵時,就會開啟此功能。請用 3 隻手指從螢幕底部向上滑動並快速放開。"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
<string name="user_switched" msgid="7249833311585228097">"目前的使用者是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1985,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"未分類"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"宣傳"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"社交"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"新聞"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"建議"</string>
<string name="importance_from_user" msgid="2782756722448800447">"你可以設定這些通知的重要性。"</string>
<string name="importance_from_person" msgid="4235804979664465383">"列為重要的原因:涉及的人。"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"自訂應用程式通知"</string>
@@ -2192,6 +2205,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕無障礙功能捷徑選擇器"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙功能捷徑"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"選單"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒體播放/暫停"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"十字鍵向上鍵"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"十字鍵向下鍵"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"十字鍵向左鍵"</string>
@@ -2418,12 +2433,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定「指紋解鎖」功能"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"由於「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"由於「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"由於「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能使用指紋解鎖手機。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"由於「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能使用指紋解鎖手機。"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定「面孔解鎖」功能"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"由於面部模型無法正常運作,因此系統已將其刪除。請重新設定,才能使用面孔解鎖手機。"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的鬧鐘"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切換使用者"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"靜音"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"輕按即可靜音"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5c3f819..d971b0f 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -160,9 +160,9 @@
<string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"在 <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>,鄰近網路使用你的「<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>」SIM 卡時,記錄了你的裝置專屬 ID (IMSI 或 IMEI)。\n\n這代表鄰近網路記錄了你的位置、活動或身分資訊。儘管這種情況很常見,但注重隱私的人可能會認為這是個問題。"</string>
<string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"已連上加密網路「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」"</string>
<string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"現在連上「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡更加安全"</string>
- <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"已連上未加密網路"</string>
- <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"目前使用「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡時,通話、訊息和資料較容易受到攻擊"</string>
- <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"目前使用「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡時,通話、訊息和資料較容易受到攻擊。\n\n連線再次加密時,你會收到另一則通知。"</string>
+ <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"連接上未加密網路"</string>
+ <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"使用目前的「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡,通話、訊息和資料較易受到攻擊"</string>
+ <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"使用目前的「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡,通話、訊息和資料較易受到攻擊。\n\n連線再次加密時,你會收到另一則通知。"</string>
<string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"行動網路安全性設定"</string>
<string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"瞭解詳情"</string>
<string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"我知道了"</string>
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"錯誤報告"</string>
<string name="global_action_logout" msgid="6093581310002476511">"結束"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"螢幕截圖"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"錯誤報告"</string>
<string name="bugreport_message" msgid="5212529146119624326">"這會收集你目前裝置狀態的相關資訊,以便透過電子郵件傳送。從錯誤報告開始建立到準備傳送的這段過程可能需要一點時間,敬請耐心等候。"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"互動式報告"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"選取即可停用無線偵錯功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"測試控管工具模式已啟用"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"恢復原廠設定以停用測試控管工具模式。"</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"已啟用序列主控台"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"效能已受到影響。如要停用,請檢查系統啟動載入程式。"</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"已啟用實驗 MTE"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"放開音量鍵。如要開啟 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時按住音量調高鍵和調低鍵 3 秒。"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"輕觸無障礙工具按鈕後,選擇你想使用的功能:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"選擇要搭配無障礙手勢 (用兩指從螢幕底部向上滑動) 使用的功能:"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"選擇要搭配無障礙手勢 (用三指從螢幕底部向上滑動) 使用的功能:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"如要切換不同的功能,請按住無障礙工具按鈕。"</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"如要切換不同的功能,請用兩指向上滑動並按住。"</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"如要切換不同的功能,請用三指向上滑動並按住。"</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
<string name="user_switched" msgid="7249833311585228097">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"未分類"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"促銷"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"社群"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"新聞"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"建議"</string>
<string name="importance_from_user" msgid="2782756722448800447">"這些通知的重要性由你決定。"</string>
<string name="importance_from_person" msgid="4235804979664465383">"這則通知涉及特定人士,因此被歸為重要通知。"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"自訂應用程式通知"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕上的無障礙捷徑選擇器"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙捷徑"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"選單"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒體播放/暫停"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad 向上移"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad 向下移"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad 向左移"</string>
@@ -2411,19 +2429,28 @@
<string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"私人空間"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"系統已隱藏含有私密資訊的通知內容"</string>
<string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
- <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面未顯示應用程式內容"</string>
+ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面隱藏了這個應用程式的內容"</string>
<string name="satellite_notification_title" msgid="4026338973463121526">"已自動連上衛星"</string>
<string name="satellite_notification_summary" msgid="5207364139430767162">"你可以收發訊息,沒有行動/Wi-Fi 網路也無妨"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定指紋解鎖"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,系統已將其刪除"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,系統已將其刪除"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能用指紋解鎖手機。"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能用指紋解鎖手機。"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定人臉解鎖"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"臉部模型無法正常運作,因此系統已將其刪除。請重新設定,才能用臉解鎖手機。"</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的鬧鐘"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切換使用者"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"靜音"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"輕觸即可設為靜音"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 8285d3e..695dc98 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -265,6 +265,8 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Umbiko wephutha"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Phothula isikhathi"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Isithombe-skrini"</string>
+ <!-- no translation found for identity_check_biometric_prompt_description (5810195983015866727) -->
+ <skip />
<string name="bugreport_title" msgid="8549990811777373050">"Umbiko wephutha"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Lokhu kuzoqoqa ulwazi mayelana nesimo samanje sedivayisi yakho, ukuthumela imilayezo ye-imeyili. Kuzothatha isikhathi esincane kusuka ekuqaleni umbiko wesiphazamiso uze ulungele ukuthunyelwa; sicela ubekezele."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Umbiko obandakanyayo"</string>
@@ -1411,6 +1413,10 @@
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Khetha ukukhubaza ukulungisa amaphutha okungenantambo."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Imodi yokuhlola i-harness inikwe amandla"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Yenza ukusetha kabusha kwasekuqaleni ukuze ukhubaze imodi yokuqina yokuhlola."</string>
+ <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+ <skip />
+ <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+ <skip />
<string name="console_running_notification_title" msgid="6087888939261635904">"I-serial console inikwe amandla"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Ukusebenza kuyathinteka. Ukuze ukhubaze, hlola i-bootloader."</string>
<string name="mte_override_notification_title" msgid="4731115381962792944">"I-Experimental MTE inikwe amandla"</string>
@@ -1755,12 +1761,18 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Khipha okhiye bevolumu. Ukuze uvule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>, cindezela bese ubamba bobabili okhiye bevolumu futhi imizuzwana emi-3."</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Khetha isici ozosisebenzisa uma uthepha inkinobho yokufinyelela:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Khetha isici ozosisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela ngaphansi kwesikrini ngeminwe emibili):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Khetha isici ozosisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela phansi esikrinini ngeminwe emithathu):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Ukuze ushintshe phakathi kwezici, thinta uphinde ubambe inkinobho yokufinyeleleka."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Ukuze ushintshe phakathi kwezici, swayiphela phezulu ngeminwe emibili uphinde ubambe."</string>
- <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Ukuze ushintshe phakathi kwezici, swayiphela phezulu ngeminwe emithathu uphinde ubambe."</string>
+ <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+ <skip />
+ <!-- no translation found for accessibility_button_instructional_text (6831154884557881996) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_instructional_text (4133877896011098550) -->
+ <skip />
+ <!-- no translation found for accessibility_gesture_3finger_instructional_text (1124458279366968154) -->
+ <skip />
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukukhuliswa"</string>
<string name="user_switched" msgid="7249833311585228097">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1988,10 @@
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ikholi eqhubekayo"</string>
<string name="call_notification_screening_text" msgid="8396931408268940208">"Ukuveza ikholi engenayo"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Akufakwanga esigabeni"</string>
+ <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Izindali"</string>
+ <string name="social_notification_channel_label" msgid="106520267132019945">"Imithombo yezokuxhumana"</string>
+ <string name="news_notification_channel_label" msgid="4299937455247883311">"Izindaba"</string>
+ <string name="recs_notification_channel_label" msgid="4945985121418684297">"Izincomo"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Usethe ukubaluleka kwalezi zaziso."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Lokhu kubalulekile ngenxa yabantu ababandakanyekayo."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Isaziso sohlelo lokusebenza olungokwezifiso"</string>
@@ -2192,6 +2208,8 @@
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Isikhethi sesinqamuleli sokufinyeleleka kusikrini"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Isinqamuleli sokufinyeleleka"</string>
<string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Cashisa Umthunzi Wesaziso"</string>
+ <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Imenyu"</string>
+ <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Ukudlala/Ukumisa Imidiya"</string>
<string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Phezulu kwe-Dpad"</string>
<string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Phansi kwe-Dpad"</string>
<string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Ngakwesokunxele se-Dpad"</string>
@@ -2418,12 +2436,21 @@
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Indlela esebenza ngayo"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setha Ukuvula ngesigxivizo somunwe futhi"</string>
- <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> ibingasebenzi kahle futhi isuliwe"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ibingasebenzi kahle futhi isuliwe"</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngesigxivizo somunwe."</string>
- <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngesigxivizo somunwe wakho"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (5851784577768803510) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7925203589860744456) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (1824812666549916586) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (5974657382960155099) -->
+ <skip />
<string name="face_dangling_notification_title" msgid="947852541060975473">"Setha Ukuvula Ngobuso futhi"</string>
- <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Imodeli yobuso yakho ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngobuso."</string>
+ <!-- no translation found for face_dangling_notification_msg (746235263598985384) -->
+ <skip />
<string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Setha"</string>
<string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hhayi manje"</string>
+ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"I-alamu ka-<xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Shintsha umsebenzisi"</string>
+ <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Thulisa"</string>
+ <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Thepha ukuze uthulise umsindo"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4883827..ea993ee 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2184,6 +2184,344 @@
<enum name="KEYCODE_DEMO_APP_2" value="302" />
<enum name="KEYCODE_DEMO_APP_3" value="303" />
<enum name="KEYCODE_DEMO_APP_4" value="304" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_DOWN" value="305" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_UP" value="306" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE" value="307" />
+ <enum name="KEYCODE_STYLUS_BUTTON_PRIMARY" value="308" />
+ <enum name="KEYCODE_STYLUS_BUTTON_SECONDARY" value="309" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TERTIARY" value="310" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TAIL" value="311" />
+ <enum name="KEYCODE_RECENT_APPS" value="312" />
+ <enum name="KEYCODE_MACRO_1" value="313" />
+ <enum name="KEYCODE_MACRO_2" value="314" />
+ <enum name="KEYCODE_MACRO_3" value="315" />
+ <enum name="KEYCODE_MACRO_4" value="316" />
+ <enum name="KEYCODE_EMOJI_PICKER" value="317" />
+ <enum name="KEYCODE_SCREENSHOT" value="318" />
+ </attr>
+
+ <!-- @hide same as keycode enum defined above, but to be used to define keycode output.
+ (redefining it to allow keycode and outKeycode to be part of same styleable attribute) -->
+ <attr name="outKeycode">
+ <enum name="KEYCODE_UNKNOWN" value="0" />
+ <enum name="KEYCODE_SOFT_LEFT" value="1" />
+ <enum name="KEYCODE_SOFT_RIGHT" value="2" />
+ <enum name="KEYCODE_HOME" value="3" />
+ <enum name="KEYCODE_BACK" value="4" />
+ <enum name="KEYCODE_CALL" value="5" />
+ <enum name="KEYCODE_ENDCALL" value="6" />
+ <enum name="KEYCODE_0" value="7" />
+ <enum name="KEYCODE_1" value="8" />
+ <enum name="KEYCODE_2" value="9" />
+ <enum name="KEYCODE_3" value="10" />
+ <enum name="KEYCODE_4" value="11" />
+ <enum name="KEYCODE_5" value="12" />
+ <enum name="KEYCODE_6" value="13" />
+ <enum name="KEYCODE_7" value="14" />
+ <enum name="KEYCODE_8" value="15" />
+ <enum name="KEYCODE_9" value="16" />
+ <enum name="KEYCODE_STAR" value="17" />
+ <enum name="KEYCODE_POUND" value="18" />
+ <enum name="KEYCODE_DPAD_UP" value="19" />
+ <enum name="KEYCODE_DPAD_DOWN" value="20" />
+ <enum name="KEYCODE_DPAD_LEFT" value="21" />
+ <enum name="KEYCODE_DPAD_RIGHT" value="22" />
+ <enum name="KEYCODE_DPAD_CENTER" value="23" />
+ <enum name="KEYCODE_VOLUME_UP" value="24" />
+ <enum name="KEYCODE_VOLUME_DOWN" value="25" />
+ <enum name="KEYCODE_POWER" value="26" />
+ <enum name="KEYCODE_CAMERA" value="27" />
+ <enum name="KEYCODE_CLEAR" value="28" />
+ <enum name="KEYCODE_A" value="29" />
+ <enum name="KEYCODE_B" value="30" />
+ <enum name="KEYCODE_C" value="31" />
+ <enum name="KEYCODE_D" value="32" />
+ <enum name="KEYCODE_E" value="33" />
+ <enum name="KEYCODE_F" value="34" />
+ <enum name="KEYCODE_G" value="35" />
+ <enum name="KEYCODE_H" value="36" />
+ <enum name="KEYCODE_I" value="37" />
+ <enum name="KEYCODE_J" value="38" />
+ <enum name="KEYCODE_K" value="39" />
+ <enum name="KEYCODE_L" value="40" />
+ <enum name="KEYCODE_M" value="41" />
+ <enum name="KEYCODE_N" value="42" />
+ <enum name="KEYCODE_O" value="43" />
+ <enum name="KEYCODE_P" value="44" />
+ <enum name="KEYCODE_Q" value="45" />
+ <enum name="KEYCODE_R" value="46" />
+ <enum name="KEYCODE_S" value="47" />
+ <enum name="KEYCODE_T" value="48" />
+ <enum name="KEYCODE_U" value="49" />
+ <enum name="KEYCODE_V" value="50" />
+ <enum name="KEYCODE_W" value="51" />
+ <enum name="KEYCODE_X" value="52" />
+ <enum name="KEYCODE_Y" value="53" />
+ <enum name="KEYCODE_Z" value="54" />
+ <enum name="KEYCODE_COMMA" value="55" />
+ <enum name="KEYCODE_PERIOD" value="56" />
+ <enum name="KEYCODE_ALT_LEFT" value="57" />
+ <enum name="KEYCODE_ALT_RIGHT" value="58" />
+ <enum name="KEYCODE_SHIFT_LEFT" value="59" />
+ <enum name="KEYCODE_SHIFT_RIGHT" value="60" />
+ <enum name="KEYCODE_TAB" value="61" />
+ <enum name="KEYCODE_SPACE" value="62" />
+ <enum name="KEYCODE_SYM" value="63" />
+ <enum name="KEYCODE_EXPLORER" value="64" />
+ <enum name="KEYCODE_ENVELOPE" value="65" />
+ <enum name="KEYCODE_ENTER" value="66" />
+ <enum name="KEYCODE_DEL" value="67" />
+ <enum name="KEYCODE_GRAVE" value="68" />
+ <enum name="KEYCODE_MINUS" value="69" />
+ <enum name="KEYCODE_EQUALS" value="70" />
+ <enum name="KEYCODE_LEFT_BRACKET" value="71" />
+ <enum name="KEYCODE_RIGHT_BRACKET" value="72" />
+ <enum name="KEYCODE_BACKSLASH" value="73" />
+ <enum name="KEYCODE_SEMICOLON" value="74" />
+ <enum name="KEYCODE_APOSTROPHE" value="75" />
+ <enum name="KEYCODE_SLASH" value="76" />
+ <enum name="KEYCODE_AT" value="77" />
+ <enum name="KEYCODE_NUM" value="78" />
+ <enum name="KEYCODE_HEADSETHOOK" value="79" />
+ <enum name="KEYCODE_FOCUS" value="80" />
+ <enum name="KEYCODE_PLUS" value="81" />
+ <enum name="KEYCODE_MENU" value="82" />
+ <enum name="KEYCODE_NOTIFICATION" value="83" />
+ <enum name="KEYCODE_SEARCH" value="84" />
+ <enum name="KEYCODE_MEDIA_PLAY_PAUSE" value="85" />
+ <enum name="KEYCODE_MEDIA_STOP" value="86" />
+ <enum name="KEYCODE_MEDIA_NEXT" value="87" />
+ <enum name="KEYCODE_MEDIA_PREVIOUS" value="88" />
+ <enum name="KEYCODE_MEDIA_REWIND" value="89" />
+ <enum name="KEYCODE_MEDIA_FAST_FORWARD" value="90" />
+ <enum name="KEYCODE_MUTE" value="91" />
+ <enum name="KEYCODE_PAGE_UP" value="92" />
+ <enum name="KEYCODE_PAGE_DOWN" value="93" />
+ <enum name="KEYCODE_PICTSYMBOLS" value="94" />
+ <enum name="KEYCODE_SWITCH_CHARSET" value="95" />
+ <enum name="KEYCODE_BUTTON_A" value="96" />
+ <enum name="KEYCODE_BUTTON_B" value="97" />
+ <enum name="KEYCODE_BUTTON_C" value="98" />
+ <enum name="KEYCODE_BUTTON_X" value="99" />
+ <enum name="KEYCODE_BUTTON_Y" value="100" />
+ <enum name="KEYCODE_BUTTON_Z" value="101" />
+ <enum name="KEYCODE_BUTTON_L1" value="102" />
+ <enum name="KEYCODE_BUTTON_R1" value="103" />
+ <enum name="KEYCODE_BUTTON_L2" value="104" />
+ <enum name="KEYCODE_BUTTON_R2" value="105" />
+ <enum name="KEYCODE_BUTTON_THUMBL" value="106" />
+ <enum name="KEYCODE_BUTTON_THUMBR" value="107" />
+ <enum name="KEYCODE_BUTTON_START" value="108" />
+ <enum name="KEYCODE_BUTTON_SELECT" value="109" />
+ <enum name="KEYCODE_BUTTON_MODE" value="110" />
+ <enum name="KEYCODE_ESCAPE" value="111" />
+ <enum name="KEYCODE_FORWARD_DEL" value="112" />
+ <enum name="KEYCODE_CTRL_LEFT" value="113" />
+ <enum name="KEYCODE_CTRL_RIGHT" value="114" />
+ <enum name="KEYCODE_CAPS_LOCK" value="115" />
+ <enum name="KEYCODE_SCROLL_LOCK" value="116" />
+ <enum name="KEYCODE_META_LEFT" value="117" />
+ <enum name="KEYCODE_META_RIGHT" value="118" />
+ <enum name="KEYCODE_FUNCTION" value="119" />
+ <enum name="KEYCODE_SYSRQ" value="120" />
+ <enum name="KEYCODE_BREAK" value="121" />
+ <enum name="KEYCODE_MOVE_HOME" value="122" />
+ <enum name="KEYCODE_MOVE_END" value="123" />
+ <enum name="KEYCODE_INSERT" value="124" />
+ <enum name="KEYCODE_FORWARD" value="125" />
+ <enum name="KEYCODE_MEDIA_PLAY" value="126" />
+ <enum name="KEYCODE_MEDIA_PAUSE" value="127" />
+ <enum name="KEYCODE_MEDIA_CLOSE" value="128" />
+ <enum name="KEYCODE_MEDIA_EJECT" value="129" />
+ <enum name="KEYCODE_MEDIA_RECORD" value="130" />
+ <enum name="KEYCODE_F1" value="131" />
+ <enum name="KEYCODE_F2" value="132" />
+ <enum name="KEYCODE_F3" value="133" />
+ <enum name="KEYCODE_F4" value="134" />
+ <enum name="KEYCODE_F5" value="135" />
+ <enum name="KEYCODE_F6" value="136" />
+ <enum name="KEYCODE_F7" value="137" />
+ <enum name="KEYCODE_F8" value="138" />
+ <enum name="KEYCODE_F9" value="139" />
+ <enum name="KEYCODE_F10" value="140" />
+ <enum name="KEYCODE_F11" value="141" />
+ <enum name="KEYCODE_F12" value="142" />
+ <enum name="KEYCODE_NUM_LOCK" value="143" />
+ <enum name="KEYCODE_NUMPAD_0" value="144" />
+ <enum name="KEYCODE_NUMPAD_1" value="145" />
+ <enum name="KEYCODE_NUMPAD_2" value="146" />
+ <enum name="KEYCODE_NUMPAD_3" value="147" />
+ <enum name="KEYCODE_NUMPAD_4" value="148" />
+ <enum name="KEYCODE_NUMPAD_5" value="149" />
+ <enum name="KEYCODE_NUMPAD_6" value="150" />
+ <enum name="KEYCODE_NUMPAD_7" value="151" />
+ <enum name="KEYCODE_NUMPAD_8" value="152" />
+ <enum name="KEYCODE_NUMPAD_9" value="153" />
+ <enum name="KEYCODE_NUMPAD_DIVIDE" value="154" />
+ <enum name="KEYCODE_NUMPAD_MULTIPLY" value="155" />
+ <enum name="KEYCODE_NUMPAD_SUBTRACT" value="156" />
+ <enum name="KEYCODE_NUMPAD_ADD" value="157" />
+ <enum name="KEYCODE_NUMPAD_DOT" value="158" />
+ <enum name="KEYCODE_NUMPAD_COMMA" value="159" />
+ <enum name="KEYCODE_NUMPAD_ENTER" value="160" />
+ <enum name="KEYCODE_NUMPAD_EQUALS" value="161" />
+ <enum name="KEYCODE_NUMPAD_LEFT_PAREN" value="162" />
+ <enum name="KEYCODE_NUMPAD_RIGHT_PAREN" value="163" />
+ <enum name="KEYCODE_VOLUME_MUTE" value="164" />
+ <enum name="KEYCODE_INFO" value="165" />
+ <enum name="KEYCODE_CHANNEL_UP" value="166" />
+ <enum name="KEYCODE_CHANNEL_DOWN" value="167" />
+ <enum name="KEYCODE_ZOOM_IN" value="168" />
+ <enum name="KEYCODE_ZOOM_OUT" value="169" />
+ <enum name="KEYCODE_TV" value="170" />
+ <enum name="KEYCODE_WINDOW" value="171" />
+ <enum name="KEYCODE_GUIDE" value="172" />
+ <enum name="KEYCODE_DVR" value="173" />
+ <enum name="KEYCODE_BOOKMARK" value="174" />
+ <enum name="KEYCODE_CAPTIONS" value="175" />
+ <enum name="KEYCODE_SETTINGS" value="176" />
+ <enum name="KEYCODE_TV_POWER" value="177" />
+ <enum name="KEYCODE_TV_INPUT" value="178" />
+ <enum name="KEYCODE_STB_POWER" value="179" />
+ <enum name="KEYCODE_STB_INPUT" value="180" />
+ <enum name="KEYCODE_AVR_POWER" value="181" />
+ <enum name="KEYCODE_AVR_INPUT" value="182" />
+ <enum name="KEYCODE_PROG_GRED" value="183" />
+ <enum name="KEYCODE_PROG_GREEN" value="184" />
+ <enum name="KEYCODE_PROG_YELLOW" value="185" />
+ <enum name="KEYCODE_PROG_BLUE" value="186" />
+ <enum name="KEYCODE_APP_SWITCH" value="187" />
+ <enum name="KEYCODE_BUTTON_1" value="188" />
+ <enum name="KEYCODE_BUTTON_2" value="189" />
+ <enum name="KEYCODE_BUTTON_3" value="190" />
+ <enum name="KEYCODE_BUTTON_4" value="191" />
+ <enum name="KEYCODE_BUTTON_5" value="192" />
+ <enum name="KEYCODE_BUTTON_6" value="193" />
+ <enum name="KEYCODE_BUTTON_7" value="194" />
+ <enum name="KEYCODE_BUTTON_8" value="195" />
+ <enum name="KEYCODE_BUTTON_9" value="196" />
+ <enum name="KEYCODE_BUTTON_10" value="197" />
+ <enum name="KEYCODE_BUTTON_11" value="198" />
+ <enum name="KEYCODE_BUTTON_12" value="199" />
+ <enum name="KEYCODE_BUTTON_13" value="200" />
+ <enum name="KEYCODE_BUTTON_14" value="201" />
+ <enum name="KEYCODE_BUTTON_15" value="202" />
+ <enum name="KEYCODE_BUTTON_16" value="203" />
+ <enum name="KEYCODE_LANGUAGE_SWITCH" value="204" />
+ <enum name="KEYCODE_MANNER_MODE" value="205" />
+ <enum name="KEYCODE_3D_MODE" value="206" />
+ <enum name="KEYCODE_CONTACTS" value="207" />
+ <enum name="KEYCODE_CALENDAR" value="208" />
+ <enum name="KEYCODE_MUSIC" value="209" />
+ <enum name="KEYCODE_CALCULATOR" value="210" />
+ <enum name="KEYCODE_ZENKAKU_HANKAKU" value="211" />
+ <enum name="KEYCODE_EISU" value="212" />
+ <enum name="KEYCODE_MUHENKAN" value="213" />
+ <enum name="KEYCODE_HENKAN" value="214" />
+ <enum name="KEYCODE_KATAKANA_HIRAGANA" value="215" />
+ <enum name="KEYCODE_YEN" value="216" />
+ <enum name="KEYCODE_RO" value="217" />
+ <enum name="KEYCODE_KANA" value="218" />
+ <enum name="KEYCODE_ASSIST" value="219" />
+ <enum name="KEYCODE_BRIGHTNESS_DOWN" value="220" />
+ <enum name="KEYCODE_BRIGHTNESS_UP" value="221" />
+ <enum name="KEYCODE_MEDIA_AUDIO_TRACK" value="222" />
+ <enum name="KEYCODE_MEDIA_SLEEP" value="223" />
+ <enum name="KEYCODE_MEDIA_WAKEUP" value="224" />
+ <enum name="KEYCODE_PAIRING" value="225" />
+ <enum name="KEYCODE_MEDIA_TOP_MENU" value="226" />
+ <enum name="KEYCODE_11" value="227" />
+ <enum name="KEYCODE_12" value="228" />
+ <enum name="KEYCODE_LAST_CHANNEL" value="229" />
+ <enum name="KEYCODE_TV_DATA_SERVICE" value="230" />
+ <enum name="KEYCODE_VOICE_ASSIST" value="231" />
+ <enum name="KEYCODE_TV_RADIO_SERVICE" value="232" />
+ <enum name="KEYCODE_TV_TELETEXT" value="233" />
+ <enum name="KEYCODE_TV_NUMBER_ENTRY" value="234" />
+ <enum name="KEYCODE_TV_TERRESTRIAL_ANALOG" value="235" />
+ <enum name="KEYCODE_TV_TERRESTRIAL_DIGITAL" value="236" />
+ <enum name="KEYCODE_TV_SATELLITE" value="237" />
+ <enum name="KEYCODE_TV_SATELLITE_BS" value="238" />
+ <enum name="KEYCODE_TV_SATELLITE_CS" value="239" />
+ <enum name="KEYCODE_TV_SATELLITE_SERVICE" value="240" />
+ <enum name="KEYCODE_TV_NETWORK" value="241" />
+ <enum name="KEYCODE_TV_ANTENNA_CABLE" value="242" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_1" value="243" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_2" value="244" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_3" value="245" />
+ <enum name="KEYCODE_TV_INPUT_HDMI_4" value="246" />
+ <enum name="KEYCODE_TV_INPUT_COMPOSITE_1" value="247" />
+ <enum name="KEYCODE_TV_INPUT_COMPOSITE_2" value="248" />
+ <enum name="KEYCODE_TV_INPUT_COMPONENT_1" value="249" />
+ <enum name="KEYCODE_TV_INPUT_COMPONENT_2" value="250" />
+ <enum name="KEYCODE_TV_INPUT_VGA_1" value="251" />
+ <enum name="KEYCODE_TV_AUDIO_DESCRIPTION" value="252" />
+ <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP" value="253" />
+ <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN" value="254" />
+ <enum name="KEYCODE_TV_ZOOM_MODE" value="255" />
+ <enum name="KEYCODE_TV_CONTENTS_MENU" value="256" />
+ <enum name="KEYCODE_TV_MEDIA_CONTEXT_MENU" value="257" />
+ <enum name="KEYCODE_TV_TIMER_PROGRAMMING" value="258" />
+ <enum name="KEYCODE_HELP" value="259" />
+ <enum name="KEYCODE_NAVIGATE_PREVIOUS" value="260" />
+ <enum name="KEYCODE_NAVIGATE_NEXT" value="261" />
+ <enum name="KEYCODE_NAVIGATE_IN" value="262" />
+ <enum name="KEYCODE_NAVIGATE_OUT" value="263" />
+ <enum name="KEYCODE_STEM_PRIMARY" value="264" />
+ <enum name="KEYCODE_STEM_1" value="265" />
+ <enum name="KEYCODE_STEM_2" value="266" />
+ <enum name="KEYCODE_STEM_3" value="267" />
+ <enum name="KEYCODE_DPAD_UP_LEFT" value="268" />
+ <enum name="KEYCODE_DPAD_DOWN_LEFT" value="269" />
+ <enum name="KEYCODE_DPAD_UP_RIGHT" value="270" />
+ <enum name="KEYCODE_DPAD_DOWN_RIGHT" value="271" />
+ <enum name="KEYCODE_MEDIA_SKIP_FORWARD" value="272" />
+ <enum name="KEYCODE_MEDIA_SKIP_BACKWARD" value="273" />
+ <enum name="KEYCODE_MEDIA_STEP_FORWARD" value="274" />
+ <enum name="KEYCODE_MEDIA_STEP_BACKWARD" value="275" />
+ <enum name="KEYCODE_SOFT_SLEEP" value="276" />
+ <enum name="KEYCODE_CUT" value="277" />
+ <enum name="KEYCODE_COPY" value="278" />
+ <enum name="KEYCODE_PASTE" value="279" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_UP" value="280" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_DOWN" value="281" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_LEFT" value="282" />
+ <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
+ <enum name="KEYCODE_ALL_APPS" value="284" />
+ <enum name="KEYCODE_REFRESH" value="285" />
+ <enum name="KEYCODE_THUMBS_UP" value="286" />
+ <enum name="KEYCODE_THUMBS_DOWN" value="287" />
+ <enum name="KEYCODE_PROFILE_SWITCH" value="288" />
+ <enum name="KEYCODE_VIDEO_APP_1" value="289" />
+ <enum name="KEYCODE_VIDEO_APP_2" value="290" />
+ <enum name="KEYCODE_VIDEO_APP_3" value="291" />
+ <enum name="KEYCODE_VIDEO_APP_4" value="292" />
+ <enum name="KEYCODE_VIDEO_APP_5" value="293" />
+ <enum name="KEYCODE_VIDEO_APP_6" value="294" />
+ <enum name="KEYCODE_VIDEO_APP_7" value="295" />
+ <enum name="KEYCODE_VIDEO_APP_8" value="296" />
+ <enum name="KEYCODE_FEATURED_APP_1" value="297" />
+ <enum name="KEYCODE_FEATURED_APP_2" value="298" />
+ <enum name="KEYCODE_FEATURED_APP_3" value="299" />
+ <enum name="KEYCODE_FEATURED_APP_4" value="300" />
+ <enum name="KEYCODE_DEMO_APP_1" value="301" />
+ <enum name="KEYCODE_DEMO_APP_2" value="302" />
+ <enum name="KEYCODE_DEMO_APP_3" value="303" />
+ <enum name="KEYCODE_DEMO_APP_4" value="304" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_DOWN" value="305" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_UP" value="306" />
+ <enum name="KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE" value="307" />
+ <enum name="KEYCODE_STYLUS_BUTTON_PRIMARY" value="308" />
+ <enum name="KEYCODE_STYLUS_BUTTON_SECONDARY" value="309" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TERTIARY" value="310" />
+ <enum name="KEYCODE_STYLUS_BUTTON_TAIL" value="311" />
+ <enum name="KEYCODE_RECENT_APPS" value="312" />
+ <enum name="KEYCODE_MACRO_1" value="313" />
+ <enum name="KEYCODE_MACRO_2" value="314" />
+ <enum name="KEYCODE_MACRO_3" value="315" />
+ <enum name="KEYCODE_MACRO_4" value="316" />
+ <enum name="KEYCODE_EMOJI_PICKER" value="317" />
+ <enum name="KEYCODE_SCREENSHOT" value="318" />
</attr>
<!-- ***************************************************************** -->
@@ -9844,6 +10182,63 @@
<attr name="productId" format="integer" />
</declare-styleable>
+ <!-- @hide -->
+ <declare-styleable name="KeyboardGlyphMap">
+ <attr name="glyphMap" format="reference" />
+ <attr name="vendorId" format="integer" />
+ <attr name="productId" format="integer" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="KeyGlyph">
+ <attr name="keycode" />
+ <attr name="glyphDrawable" format="reference" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="ModifierGlyph">
+ <!-- The values are taken from public constants for modifier state defined in
+ {@see KeyEvent.java}. Here we explicitly allow only one modifier bit as value, since
+ this represents the modifier key -->
+ <attr name="modifier">
+ <enum name="META" value="0x10000" />
+ <enum name="CTRL" value="0x1000" />
+ <enum name="ALT" value="0x02" />
+ <enum name="SHIFT" value="0x1" />
+ <enum name="SYM" value="0x4" />
+ <enum name="FUNCTION" value="0x8" />
+ <enum name="CAPS_LOCK" value="0x100000" />
+ <enum name="NUM_LOCK" value="0x200000" />
+ <enum name="SCROLL_LOCK" value="0x400000" />
+ </attr>
+ <attr name="glyphDrawable" format="reference" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="HardwareDefinedShortcut">
+ <attr name="keycode" />
+ <!-- The values are taken from public constants for modifier state defined in
+ {@see KeyEvent.java}. Here we allow multiple modifier flags as value, since this
+ represents the modifier state -->
+ <attr name="modifierState">
+ <flag name="META" value="0x10000" />
+ <flag name="CTRL" value="0x1000" />
+ <flag name="ALT" value="0x02" />
+ <flag name="SHIFT" value="0x1" />
+ <flag name="SYM" value="0x4" />
+ <flag name="FUNCTION" value="0x8" />
+ <flag name="CAPS_LOCK" value="0x100000" />
+ <flag name="NUM_LOCK" value="0x200000" />
+ <flag name="SCROLL_LOCK" value="0x400000" />
+ </attr>
+ <attr name="outKeycode" />
+ </declare-styleable>
+
+ <!-- @hide -->
+ <declare-styleable name="FunctionRowKey">
+ <attr name="keycode" />
+ </declare-styleable>
+
<declare-styleable name="MediaRouteButton">
<!-- This drawable is a state list where the "activated" state
indicates active media routing. Non-activated indicates
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 37412a0..f5bb554 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -480,17 +480,17 @@
<!-- Colors used in Android system, from design system.
These values can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_primary_container_light">#5E73A9</color>
- <color name="system_on_primary_container_light">#FFFFFF</color>
- <color name="system_primary_light">#2A4174</color>
+ <color name="system_primary_container_light">#D9E2FF</color>
+ <color name="system_on_primary_container_light">#001945</color>
+ <color name="system_primary_light">#475D92</color>
<color name="system_on_primary_light">#FFFFFF</color>
- <color name="system_secondary_container_light">#6E7488</color>
- <color name="system_on_secondary_container_light">#FFFFFF</color>
- <color name="system_secondary_light">#3C4255</color>
+ <color name="system_secondary_container_light">#DCE2F9</color>
+ <color name="system_on_secondary_container_light">#151B2C</color>
+ <color name="system_secondary_light">#575E71</color>
<color name="system_on_secondary_light">#FFFFFF</color>
- <color name="system_tertiary_container_light">#8A6A89</color>
- <color name="system_on_tertiary_container_light">#FFFFFF</color>
- <color name="system_tertiary_light">#553A55</color>
+ <color name="system_tertiary_container_light">#FDD7FA</color>
+ <color name="system_on_tertiary_container_light">#2A122C</color>
+ <color name="system_tertiary_light">#725572</color>
<color name="system_on_tertiary_light">#FFFFFF</color>
<color name="system_background_light">#FAF8FF</color>
<color name="system_on_background_light">#1A1B20</color>
@@ -504,17 +504,17 @@
<color name="system_surface_bright_light">#FAF8FF</color>
<color name="system_surface_dim_light">#DAD9E0</color>
<color name="system_surface_variant_light">#E1E2EC</color>
- <color name="system_on_surface_variant_light">#40434B</color>
- <color name="system_outline_light">#5D5F67</color>
- <color name="system_outline_variant_light">#797A83</color>
- <color name="system_error_light">#8C0009</color>
+ <color name="system_on_surface_variant_light">#44464F</color>
+ <color name="system_outline_light">#757780</color>
+ <color name="system_outline_variant_light">#C5C6D0</color>
+ <color name="system_error_light">#BA1A1A</color>
<color name="system_on_error_light">#FFFFFF</color>
- <color name="system_error_container_light">#DA342E</color>
- <color name="system_on_error_container_light">#FFFFFF</color>
+ <color name="system_error_container_light">#FFDAD6</color>
+ <color name="system_on_error_container_light">#410002</color>
<color name="system_control_activated_light">#D9E2FF</color>
<color name="system_control_normal_light">#44464F</color>
<color name="system_control_highlight_light">#000000</color>
- <color name="system_text_primary_inverse_light">#E2E2E9</color>
+<color name="system_text_primary_inverse_light">#E2E2E9</color>
<color name="system_text_secondary_and_tertiary_inverse_light">#C5C6D0</color>
<color name="system_text_primary_inverse_disable_only_light">#E2E2E9</color>
<color name="system_text_secondary_and_tertiary_inverse_disabled_light">#E2E2E9</color>
@@ -524,22 +524,22 @@
<color name="system_palette_key_color_tertiary_light">#8C6D8C</color>
<color name="system_palette_key_color_neutral_light">#76777D</color>
<color name="system_palette_key_color_neutral_variant_light">#757780</color>
- <color name="system_primary_container_dark">#7A90C8</color>
- <color name="system_on_primary_container_dark">#000000</color>
- <color name="system_primary_dark">#B7CAFF</color>
- <color name="system_on_primary_dark">#00143B</color>
- <color name="system_secondary_container_dark">#8A90A5</color>
- <color name="system_on_secondary_container_dark">#000000</color>
- <color name="system_secondary_dark">#C4CAE1</color>
- <color name="system_on_secondary_dark">#0F1626</color>
- <color name="system_tertiary_container_dark">#A886A6</color>
- <color name="system_on_tertiary_container_dark">#000000</color>
- <color name="system_tertiary_dark">#E4BFE2</color>
- <color name="system_on_tertiary_dark">#240D26</color>
+ <color name="system_primary_container_dark">#2F4578</color>
+ <color name="system_on_primary_container_dark">#D9E2FF</color>
+ <color name="system_primary_dark">#B0C6FF</color>
+ <color name="system_on_primary_dark">#152E60</color>
+ <color name="system_secondary_container_dark">#404659</color>
+ <color name="system_on_secondary_container_dark">#DCE2F9</color>
+ <color name="system_secondary_dark">#C0C6DC</color>
+ <color name="system_on_secondary_dark">#2A3042</color>
+ <color name="system_tertiary_container_dark">#593D59</color>
+ <color name="system_on_tertiary_container_dark">#FDD7FA</color>
+ <color name="system_tertiary_dark">#E0BBDD</color>
+ <color name="system_on_tertiary_dark">#412742</color>
<color name="system_background_dark">#121318</color>
<color name="system_on_background_dark">#E2E2E9</color>
<color name="system_surface_dark">#121318</color>
- <color name="system_on_surface_dark">#FCFAFF</color>
+ <color name="system_on_surface_dark">#E2E2E9</color>
<color name="system_surface_container_low_dark">#1A1B20</color>
<color name="system_surface_container_lowest_dark">#0C0E13</color>
<color name="system_surface_container_dark">#1E1F25</color>
@@ -548,13 +548,13 @@
<color name="system_surface_bright_dark">#38393F</color>
<color name="system_surface_dim_dark">#121318</color>
<color name="system_surface_variant_dark">#44464F</color>
- <color name="system_on_surface_variant_dark">#C9CAD4</color>
- <color name="system_outline_dark">#A1A2AC</color>
- <color name="system_outline_variant_dark">#81838C</color>
- <color name="system_error_dark">#FFBAB1</color>
- <color name="system_on_error_dark">#370001</color>
- <color name="system_error_container_dark">#FF5449</color>
- <color name="system_on_error_container_dark">#000000</color>
+ <color name="system_on_surface_variant_dark">#C5C6D0</color>
+ <color name="system_outline_dark">#8F9099</color>
+ <color name="system_outline_variant_dark">#44464F</color>
+ <color name="system_error_dark">#FFB4AB</color>
+ <color name="system_on_error_dark">#690005</color>
+ <color name="system_error_container_dark">#93000A</color>
+ <color name="system_on_error_container_dark">#FFDAD6</color>
<color name="system_control_activated_dark">#2F4578</color>
<color name="system_control_normal_dark">#C5C6D0</color>
<color name="system_control_highlight_dark">#FFFFFF</color>
@@ -568,63 +568,63 @@
<color name="system_palette_key_color_tertiary_dark">#8C6D8C</color>
<color name="system_palette_key_color_neutral_dark">#76777D</color>
<color name="system_palette_key_color_neutral_variant_dark">#757780</color>
- <color name="system_primary_fixed">#5E73A9</color>
- <color name="system_primary_fixed_dim">#455B8F</color>
- <color name="system_on_primary_fixed">#FFFFFF</color>
- <color name="system_on_primary_fixed_variant">#FFFFFF</color>
- <color name="system_secondary_fixed">#6E7488</color>
- <color name="system_secondary_fixed_dim">#555C6F</color>
- <color name="system_on_secondary_fixed">#FFFFFF</color>
- <color name="system_on_secondary_fixed_variant">#FFFFFF</color>
- <color name="system_tertiary_fixed">#8A6A89</color>
- <color name="system_tertiary_fixed_dim">#705270</color>
- <color name="system_on_tertiary_fixed">#FFFFFF</color>
- <color name="system_on_tertiary_fixed_variant">#FFFFFF</color>
+ <color name="system_primary_fixed">#D9E2FF</color>
+ <color name="system_primary_fixed_dim">#B0C6FF</color>
+ <color name="system_on_primary_fixed">#001945</color>
+ <color name="system_on_primary_fixed_variant">#2F4578</color>
+ <color name="system_secondary_fixed">#DCE2F9</color>
+ <color name="system_secondary_fixed_dim">#C0C6DC</color>
+ <color name="system_on_secondary_fixed">#151B2C</color>
+ <color name="system_on_secondary_fixed_variant">#404659</color>
+ <color name="system_tertiary_fixed">#FDD7FA</color>
+ <color name="system_tertiary_fixed_dim">#E0BBDD</color>
+ <color name="system_on_tertiary_fixed">#2A122C</color>
+ <color name="system_on_tertiary_fixed_variant">#593D59</color>
<!--Colors used in Android system, from design system. These values can be overlaid at runtime
by OverlayManager RROs.-->
<color name="system_widget_background_light">#EEF0FF</color>
- <color name="system_clock_hour_light">#1D2435</color>
- <color name="system_clock_minute_light">#20386A</color>
- <color name="system_clock_second_light">#000000</color>
- <color name="system_theme_app_light">#2F4578</color>
- <color name="system_on_theme_app_light">#D6DFFF</color>
+ <color name="system_clock_hour_light">#373D50</color>
+ <color name="system_clock_minute_light">#3D5487</color>
+ <color name="system_clock_second_light">#4F659A</color>
+ <color name="system_theme_app_light">#D9E2FF</color>
+ <color name="system_on_theme_app_light">#475D92</color>
<color name="system_theme_app_ring_light">#94AAE4</color>
- <color name="system_theme_notif_light">#FDD7FA</color>
- <color name="system_brand_a_light">#3A5084</color>
+ <color name="system_theme_notif_light">#E0BBDD</color>
+ <color name="system_brand_a_light">#475D92</color>
<color name="system_brand_b_light">#6E7488</color>
- <color name="system_brand_c_light">#6076AC</color>
- <color name="system_brand_d_light">#8C6D8C</color>
+ <color name="system_brand_c_light">#5E73A9</color>
+ <color name="system_brand_d_light">#8A6A89</color>
<color name="system_under_surface_light">#000000</color>
- <color name="system_shade_active_light">#D9E2FF</color>
+<color name="system_shade_active_light">#D9E2FF</color>
<color name="system_on_shade_active_light">#152E60</color>
<color name="system_on_shade_active_variant_light">#2F4578</color>
<color name="system_shade_inactive_light">#2F3036</color>
<color name="system_on_shade_inactive_light">#E1E2EC</color>
<color name="system_on_shade_inactive_variant_light">#C5C6D0</color>
<color name="system_shade_disabled_light">#0C0E13</color>
- <color name="system_overview_background_light">#50525A</color>
+ <color name="system_overview_background_light">#C5C6D0</color>
<color name="system_widget_background_dark">#152E60</color>
- <color name="system_clock_hour_dark">#9AA0B6</color>
- <color name="system_clock_minute_dark">#D8E1FF</color>
- <color name="system_clock_second_dark">#FFFFFF</color>
- <color name="system_theme_app_dark">#D9E2FF</color>
- <color name="system_on_theme_app_dark">#304679</color>
+ <color name="system_clock_hour_dark">#8A90A5</color>
+ <color name="system_clock_minute_dark">#D9E2FF</color>
+ <color name="system_clock_second_dark">#B0C6FF</color>
+ <color name="system_theme_app_dark">#2F4578</color>
+ <color name="system_on_theme_app_dark">#B0C6FF</color>
<color name="system_theme_app_ring_dark">#94AAE4</color>
- <color name="system_theme_notif_dark">#E0BBDD</color>
- <color name="system_brand_a_dark">#90A6DF</color>
- <color name="system_brand_b_dark">#A4ABC1</color>
+ <color name="system_theme_notif_dark">#FDD7FA</color>
+ <color name="system_brand_a_dark">#B0C6FF</color>
+ <color name="system_brand_b_dark">#DCE2F9</color>
<color name="system_brand_c_dark">#7A90C8</color>
- <color name="system_brand_d_dark">#A886A6</color>
+ <color name="system_brand_d_dark">#FDD7FA</color>
<color name="system_under_surface_dark">#000000</color>
- <color name="system_shade_active_dark">#D9E2FF</color>
+<color name="system_shade_active_dark">#D9E2FF</color>
<color name="system_on_shade_active_dark">#001945</color>
<color name="system_on_shade_active_variant_dark">#2F4578</color>
<color name="system_shade_inactive_dark">#2F3036</color>
<color name="system_on_shade_inactive_dark">#E1E2EC</color>
<color name="system_on_shade_inactive_variant_dark">#C5C6D0</color>
<color name="system_shade_disabled_dark">#0C0E13</color>
- <color name="system_overview_background_dark">#C5C6D0</color>
+ <color name="system_overview_background_dark">#50525A</color>
<!-- Accessibility shortcut icon background color -->
<color name="accessibility_feature_background">#5F6368</color> <!-- Google grey 700 -->
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index e983427..61c7a8c 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -424,4 +424,11 @@
<bool name="config_dropboxmanager_persistent_logging_enabled">false</bool>
<java-symbol type="bool" name="config_dropboxmanager_persistent_logging_enabled" />
+ <!-- Telephony satellite gateway class name for handling carrier roaming to satellite is using ESOS messaging. -->
+ <string name="config_satellite_carrier_roaming_esos_provisioned_class" translatable="false"></string>
+ <java-symbol type="string" name="config_satellite_carrier_roaming_esos_provisioned_class" />
+
+ <!-- Telephony satellite gateway intent for handling carrier roaming to satellite is using ESOS messaging. -->
+ <string name="config_satellite_carrier_roaming_esos_provisioned_intent_action" translatable="false"></string>
+ <java-symbol type="string" name="config_satellite_carrier_roaming_esos_provisioned_intent_action" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9d1e86b..6b71f97 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4853,11 +4853,11 @@
<string name="accessibility_gesture_3finger_prompt_text">Choose a feature</string>
<!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button in the navigation bar. [CHAR LIMIT=none]-->
- <string name="accessibility_button_instructional_text">The feature will open next time you tap the accessibility button.</string>
+ <string name="accessibility_button_instructional_text">The feature will open next time you tap the accessibility button</string>
<!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation is enabled. [CHAR LIMIT=none] -->
- <string name="accessibility_gesture_instructional_text">The feature will open next time you use this shortcut. Swipe up with two fingers from the bottom of your screen and release quickly.</string>
+ <string name="accessibility_gesture_instructional_text">The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly.</string>
<!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation and TalkBack is enabled. [CHAR LIMIT=none] -->
- <string name="accessibility_gesture_3finger_instructional_text">The feature will open next time you use this shortcut. Swipe up with three fingers from the bottom of your screen and release quickly.</string>
+ <string name="accessibility_gesture_3finger_instructional_text">The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly.</string>
<!-- Text used to describe system navigation features, shown within a UI allowing a user to assign system magnification features to the Accessibility button in the navigation bar. -->
<string name="accessibility_magnification_chooser_text">Magnification</string>
@@ -6508,19 +6508,30 @@
<!-- Fingerprint dangling notification title -->
<string name="fingerprint_dangling_notification_title">Set up Fingerprint Unlock again</string>
<!-- Fingerprint dangling notification content for only 1 fingerprint deleted -->
- <string name="fingerprint_dangling_notification_msg_1"><xliff:g id="fingerprint">%s</xliff:g> wasn\'t working well and was deleted</string>
+ <string name="fingerprint_dangling_notification_msg_1"><xliff:g id="fingerprint">%s</xliff:g> can no longer be recognized.</string>
<!-- Fingerprint dangling notification content for more than 1 fingerprints deleted -->
- <string name="fingerprint_dangling_notification_msg_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> weren\'t working well and were deleted</string>
+ <string name="fingerprint_dangling_notification_msg_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> can no longer be recognized.</string>
<!-- Fingerprint dangling notification content for only 1 fingerprint deleted and no fingerprint left-->
- <string name="fingerprint_dangling_notification_msg_all_deleted_1"><xliff:g id="fingerprint">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint.</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_1"><xliff:g id="fingerprint">%s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again.</string>
<!-- Fingerprint dangling notification content for more than 1 fingerprints deleted and no fingerprint left -->
- <string name="fingerprint_dangling_notification_msg_all_deleted_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint.</string>
+ <string name="fingerprint_dangling_notification_msg_all_deleted_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again.</string>
<!-- Face dangling notification title -->
<string name="face_dangling_notification_title">Set up Face Unlock again</string>
<!-- Face dangling notification content -->
- <string name="face_dangling_notification_msg">Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face.</string>
+ <string name="face_dangling_notification_msg">Your face model can no longer be recognized. Set up Face Unlock again.</string>
<!-- Biometric dangling notification "set up" action button -->
<string name="biometric_dangling_notification_action_set_up">Set up</string>
<!-- Biometric dangling notification "Not now" action button -->
<string name="biometric_dangling_notification_action_not_now">Not now</string>
+
+
+ <!-- Background user sound notification related messages -->
+ <!-- Notification title when sound comes from an alarm or timer on background user [CHAR LIMIT=NOTIF_TITLE]-->
+ <string name="bg_user_sound_notification_title_alarm">Alarm for <xliff:g id="user_name" example="John Doe">%s</xliff:g></string>
+ <!-- Notification action button to prompt user switch to the background user [CHAR LIMIT=NONE] -->
+ <string name="bg_user_sound_notification_button_switch_user">Switch user</string>
+ <!-- Notification action button to mute the sound from the background user [CHAR LIMIT=NONE] -->
+ <string name="bg_user_sound_notification_button_mute">Mute</string>
+ <!-- Notification text to mute the sound from the background user [CHAR LIMIT=NOTIF_BODY]-->
+ <string name="bg_user_sound_notification_message">Tap to mute sound</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9a2aafd..7d50d22 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1753,6 +1753,15 @@
<java-symbol type="anim" name="task_fragment_clear_top_close_exit" />
<java-symbol type="anim" name="task_fragment_clear_top_open_enter" />
<java-symbol type="anim" name="task_fragment_clear_top_open_exit" />
+ <java-symbol type="anim" name="overlay_task_fragment_open_from_left" />
+ <java-symbol type="anim" name="overlay_task_fragment_open_from_top" />
+ <java-symbol type="anim" name="overlay_task_fragment_open_from_right" />
+ <java-symbol type="anim" name="overlay_task_fragment_open_from_bottom" />
+ <java-symbol type="anim" name="overlay_task_fragment_change" />
+ <java-symbol type="anim" name="overlay_task_fragment_close_to_left" />
+ <java-symbol type="anim" name="overlay_task_fragment_close_to_top" />
+ <java-symbol type="anim" name="overlay_task_fragment_close_to_right" />
+ <java-symbol type="anim" name="overlay_task_fragment_close_to_bottom" />
<java-symbol type="array" name="config_autoRotationTiltTolerance" />
<java-symbol type="array" name="config_longPressVibePattern" />
@@ -5540,4 +5549,10 @@
<java-symbol type="drawable" name="ic_zen_mode_type_schedule_time" />
<java-symbol type="drawable" name="ic_zen_mode_type_theater" />
<java-symbol type="drawable" name="ic_zen_mode_type_unknown" />
+
+ <!-- System notification for background user sound -->
+ <java-symbol type="string" name="bg_user_sound_notification_title_alarm" />
+ <java-symbol type="string" name="bg_user_sound_notification_button_switch_user" />
+ <java-symbol type="string" name="bg_user_sound_notification_button_mute" />
+ <java-symbol type="string" name="bg_user_sound_notification_message" />
</resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 67cceb5..581dee5 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -185,6 +185,9 @@
https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf -->
<shortcode country="it" pattern="\\d{5}" premium="44[0-4]\\d{2}|47[0-4]\\d{2}|48[0-4]\\d{2}|44[5-9]\\d{4}|47[5-9]\\d{4}|48[5-9]\\d{4}|455\\d{2}|499\\d{2}" free="116\\d{3}|4112503|40\\d{0,12}" standard="430\\d{2}|431\\d{2}|434\\d{4}|435\\d{4}|439\\d{7}" />
+ <!-- Jordan: 1-5 digits (standard system default, not country specific) -->
+ <shortcode country="jo" pattern="\\d{1,5}" free="99066" />
+
<!-- Japan: 8083 used by SOFTBANK_DCB_2 -->
<shortcode country="jp" pattern="\\d{1,5}" free="8083" />
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index 6b3cf7b..ee1b658 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -44,7 +44,6 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -382,8 +381,7 @@
assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
- assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
- .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
+ assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
// Revert the ResourcesManager instance back.
ResourcesManager.setInstance(oriResourcesManager);
@@ -414,9 +412,7 @@
assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
- assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
- .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
-
+ assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
// Revert the ResourcesManager instance back.
ResourcesManager.setInstance(oriResourcesManager);
}
@@ -452,9 +448,7 @@
assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
- assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
- .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
-
+ assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
// Revert the ResourcesManager instance back.
ResourcesManager.setInstance(oriResourcesManager);
}
@@ -493,9 +487,7 @@
assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
// Package resources' paths should be cached in ResourcesManager.
- assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
- .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
-
+ assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
// Revert the ResourcesManager instance back.
ResourcesManager.setInstance(oriResourcesManager);
}
diff --git a/core/tests/coretests/src/android/graphics/ColorStateListTest.java b/core/tests/coretests/src/android/graphics/ColorStateListTest.java
index a3d52ea..ab41bd0 100644
--- a/core/tests/coretests/src/android/graphics/ColorStateListTest.java
+++ b/core/tests/coretests/src/android/graphics/ColorStateListTest.java
@@ -19,6 +19,8 @@
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.test.AndroidTestCase;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
import androidx.test.filters.SmallTest;
@@ -49,6 +51,15 @@
}
@SmallTest
+ public void testStateIsInList_proto() throws Exception {
+ ColorStateList colorStateList = recreateFromProto(
+ mResources.getColorStateList(R.color.color1));
+ int[] focusedState = {android.R.attr.state_focused};
+ int focusColor = colorStateList.getColorForState(focusedState, R.color.failColor);
+ assertEquals(mResources.getColor(R.color.testcolor1), focusColor);
+ }
+
+ @SmallTest
public void testEmptyState() throws Exception {
ColorStateList colorStateList = mResources.getColorStateList(R.color.color1);
int[] emptyState = {};
@@ -57,6 +68,15 @@
}
@SmallTest
+ public void testEmptyState_proto() throws Exception {
+ ColorStateList colorStateList = recreateFromProto(
+ mResources.getColorStateList(R.color.color1));
+ int[] emptyState = {};
+ int defaultColor = colorStateList.getColorForState(emptyState, mFailureColor);
+ assertEquals(mResources.getColor(R.color.testcolor2), defaultColor);
+ }
+
+ @SmallTest
public void testGetColor() throws Exception {
int defaultColor = mResources.getColor(R.color.color1);
assertEquals(mResources.getColor(R.color.testcolor2), defaultColor);
@@ -73,4 +93,11 @@
int defaultColor = mResources.getColor(R.color.color_with_lstar);
assertEquals(mResources.getColor(R.color.testcolor3), defaultColor);
}
+
+ private ColorStateList recreateFromProto(ColorStateList colorStateList) throws Exception {
+ ProtoOutputStream out = new ProtoOutputStream();
+ colorStateList.writeToProto(out);
+ ProtoInputStream in = new ProtoInputStream(out.getBytes());
+ return ColorStateList.createFromProto(in);
+ }
}
diff --git a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
index 58e5be2..4d9b591c 100644
--- a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
+++ b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
@@ -34,6 +34,7 @@
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
+import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Insets;
import android.platform.test.annotations.Presubmit;
@@ -102,6 +103,8 @@
mViewRoot.setOnContentApplyWindowInsetsListener(
mock(Window.OnContentApplyWindowInsetsListener.class));
mBackAnimationController = new ImeBackAnimationController(mViewRoot, mInsetsController);
+ mViewRoot.mContext.getResources().getConfiguration().windowConfiguration
+ .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
when(mWindowInsetsAnimationController.getHiddenStateInsets()).thenReturn(Insets.NONE);
when(mWindowInsetsAnimationController.getShownStateInsets()).thenReturn(IME_INSETS);
@@ -156,8 +159,28 @@
mBackAnimationController.onBackProgressed(new BackEvent(100f, 0f, 0.5f, EDGE_LEFT));
// commit back gesture
mBackAnimationController.onBackInvoked();
- // verify that InsetsController#hide is called
- verify(mInsetsController, times(1)).hide(ime());
+ // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
+ // getInputMethodManager is called from ImeBackAnimationController)
+ verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
+ // verify that ImeBackAnimationController does not take control over IME insets
+ verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
+ anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
+ }
+
+ @Test
+ public void testMultiWindowModeNotPlayingAnim() {
+ // setup ViewRoot with WINDOWING_MODE_MULTI_WINDOW
+ mViewRoot.mContext.getResources().getConfiguration().windowConfiguration.setWindowingMode(
+ WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+ // start back gesture
+ mBackAnimationController.onBackStarted(new BackEvent(0f, 0f, 0f, EDGE_LEFT));
+ // progress back gesture
+ mBackAnimationController.onBackProgressed(new BackEvent(100f, 0f, 0.5f, EDGE_LEFT));
+ // commit back gesture
+ mBackAnimationController.onBackInvoked();
+ // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
+ // getInputMethodManager is called from ImeBackAnimationController)
+ verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
// verify that ImeBackAnimationController does not take control over IME insets
verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
@@ -277,9 +300,9 @@
// commit back gesture
mBackAnimationController.onBackInvoked();
-
- // verify that InsetsController#hide is called
- verify(mInsetsController, times(1)).hide(ime());
+ // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
+ // getInputMethodManager is called from ImeBackAnimationController)
+ verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
});
}
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index 169300a..c01b51d 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -21,6 +21,7 @@
import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
@@ -121,6 +122,52 @@
waitForAfterDraw();
}
+ @Test
+ @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
+ FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
+ public void inputMethodWithContentMoves() throws Throwable {
+ if (!ViewProperties.vrr_enabled().orElse(true)) {
+ return;
+ }
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+ // update the window type to TYPE_INPUT_METHOD
+ int windowType = mViewRoot.mWindowAttributes.type;
+ final WindowManager.LayoutParams attrs = mViewRoot.mWindowAttributes;
+ attrs.type = TYPE_INPUT_METHOD;
+ instrumentation.runOnMainSync(() -> {
+ mViewRoot.setLayoutParams(attrs, false);
+ });
+ instrumentation.waitForIdleSync();
+
+ final WindowManager.LayoutParams newAttrs = mViewRoot.mWindowAttributes;
+ assertTrue(newAttrs.type == TYPE_INPUT_METHOD);
+
+ waitForFrameRateCategoryToSettle();
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.offsetLeftAndRight(100);
+ runAfterDraw(() -> {
+ if (toolkitFrameRateVelocityMappingReadOnly()) {
+ float frameRate = mViewRoot.getLastPreferredFrameRate();
+ // frame rate shouldn't be boost with TYPE_INPUT_METHOD window type
+ assertTrue(frameRate == 0);
+ } else {
+ assertEquals(FRAME_RATE_CATEGORY_HIGH,
+ mViewRoot.getLastPreferredFrameRateCategory());
+ }
+ });
+ });
+ waitForAfterDraw();
+
+ // Reset the window type back to the original one.
+ newAttrs.type = windowType;
+ instrumentation.runOnMainSync(() -> {
+ mViewRoot.setLayoutParams(newAttrs, false);
+ });
+ instrumentation.waitForIdleSync();
+ assertTrue(mViewRoot.mWindowAttributes.type == windowType);
+ }
+
@UiThreadTest
@Test
@RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
@@ -128,6 +175,87 @@
assertEquals(0f, mViewRoot.getLastPreferredFrameRate(), 0f);
}
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
+ public void highHintWhenActionMove() throws Throwable {
+ if (!ViewProperties.vrr_enabled().orElse(true)) {
+ return;
+ }
+
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_LOW);
+ ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+ layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+ mMovingView.setLayoutParams(layoutParams);
+ mMovingView.setOnClickListener((v) -> {});
+ });
+ waitForFrameRateCategoryToSettle();
+ mActivityRule.runOnUiThread(() -> assertEquals(FRAME_RATE_CATEGORY_LOW,
+ mViewRoot.getLastPreferredFrameRateCategory()));
+
+ int[] position = new int[2];
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.getLocationOnScreen(position);
+ position[0] += mMovingView.getWidth() / 2;
+ position[1] += mMovingView.getHeight() / 2;
+ });
+ final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+ long now = SystemClock.uptimeMillis();
+ MotionEvent down = MotionEvent.obtain(
+ now, // downTime
+ now, // eventTime
+ MotionEvent.ACTION_DOWN, // action
+ position[0], // x
+ position[1], // y
+ 0 // metaState
+ );
+ down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ instrumentation.sendPointerSync(down);
+
+ now = SystemClock.uptimeMillis();
+ MotionEvent move = MotionEvent.obtain(
+ now, // downTime
+ now, // eventTime
+ MotionEvent.ACTION_MOVE, // action
+ position[0], // x
+ position[1], // y
+ 0 // metaState
+ );
+ move.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ instrumentation.sendPointerSync(move);
+
+ // We should continue to enable touch boost even when GTE compatibility is present.
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.offsetLeftAndRight(10);
+ assertTrue(mViewRoot.getIsTouchBoosting());
+ });
+
+ now = SystemClock.uptimeMillis();
+ MotionEvent up = MotionEvent.obtain(
+ now, // downTime
+ now, // eventTime
+ MotionEvent.ACTION_UP, // action
+ position[0], // x
+ position[1], // y
+ 0 // metaState
+ );
+ up.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ instrumentation.sendPointerSync(up);
+
+ // No touch boost when there is no ongoing pressed gesture.
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.offsetLeftAndRight(10);
+ assertFalse(mViewRoot.getIsTouchBoosting());
+ });
+
+ down.recycle();
+ move.recycle();
+ up.recycle();
+ }
+
@Test
@RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
public void frameBoostDisable() throws Throwable {
@@ -161,7 +289,7 @@
@RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY,
FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
- public void lowVelocity60() throws Throwable {
+ public void lowVelocity80() throws Throwable {
if (!ViewProperties.vrr_enabled().orElse(true)) {
return;
}
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index b153700..9337bf6 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -16,13 +16,6 @@
package android.view;
-import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
-import static android.view.flags.Flags.FLAG_ADD_SCHANDLE_TO_VRI_SURFACE;
-import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
-import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY;
-import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY;
-import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
-import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
@@ -44,6 +37,13 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
+import static android.view.flags.Flags.FLAG_ADD_SCHANDLE_TO_VRI_SURFACE;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
+import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
import static android.view.flags.Flags.toolkitFrameRateDefaultNormalReadOnly;
import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
@@ -53,6 +53,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -63,9 +64,11 @@
import android.app.UiModeManager;
import android.content.Context;
import android.graphics.ForceDarkType;
+import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Binder;
import android.os.SystemProperties;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -1540,6 +1543,37 @@
nativeCreateASurfaceControlFromSurface(mViewRootImpl.mSurface));
}
+ @EnableFlags(Flags.FLAG_INSETS_CONTROL_SEQ)
+ @Test
+ public void testHandleInsetsControlChanged() {
+ mView = new View(sContext);
+ attachViewToWindow(mView);
+
+ mViewRootImpl = mView.getViewRootImpl();
+ final InsetsController controller = mViewRootImpl.getInsetsController();
+
+ final InsetsState state0 = new InsetsState();
+ final InsetsState state1 = new InsetsState();
+ state0.setDisplayFrame(new Rect(0, 0, 500, 1000));
+ state0.setSeq(10000);
+ state1.setDisplayFrame(new Rect(0, 0, 1500, 2000));
+ state1.setSeq(10001);
+ final InsetsSourceControl.Array array = new InsetsSourceControl.Array();
+
+ sInstrumentation.runOnMainSync(() -> {
+ mViewRootImpl.handleInsetsControlChanged(state0, array);
+ assertEquals(state0, controller.getLastDispatchedState());
+
+ mViewRootImpl.handleInsetsControlChanged(state1, array);
+ assertEquals(state1, controller.getLastDispatchedState());
+
+ // Skip the stale value.
+ mViewRootImpl.handleInsetsControlChanged(state0, array);
+ assertEquals(state1, controller.getLastDispatchedState());
+ assertNotEquals(state0, controller.getLastDispatchedState());
+ });
+ }
+
private boolean setForceDarkSysProp(boolean isForceDarkEnabled) {
try {
SystemProperties.set(
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetTest.java b/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetTest.java
index 389b677..f01ac6f 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetTest.java
@@ -16,15 +16,22 @@
package com.android.internal.accessibility.dialog;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.google.common.truth.Truth.assertThat;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Flags;
+
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.accessibility.common.ShortcutConstants;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,9 +39,13 @@
@RunWith(AndroidJUnit4.class)
public class AccessibilityTargetTest {
+ @Rule
+ public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final int[] EXPECTED_TYPES = { HARDWARE, SOFTWARE };
+ private static final int[] EXPECTED_TYPES_GESTURE = { HARDWARE, SOFTWARE, GESTURE };
@Test
+ @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
public void isRecognizedShortcutType_expectedType_isTrue() {
for (int type : EXPECTED_TYPES) {
assertThat(AccessibilityTarget.isRecognizedShortcutType(type)).isTrue();
@@ -42,6 +53,7 @@
}
@Test
+ @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
public void isRecognizedShortcutType_notExpectedType_isFalse() {
for (int type: ShortcutConstants.USER_SHORTCUT_TYPES) {
if (IntStream.of(EXPECTED_TYPES).noneMatch(x -> x == type)) {
@@ -49,4 +61,28 @@
}
}
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+ public void isRecognizedShortcutType_expectedType_gestureIncluded_isTrue() {
+ for (int type : EXPECTED_TYPES_GESTURE) {
+ if (!AccessibilityTarget.isRecognizedShortcutType(type)) {
+ throw new AssertionError(
+ "Shortcut type " + type + " should be recognized");
+ }
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+ public void isRecognizedShortcutType_notExpectedType_gestureIncluded_isFalse() {
+ for (int type: ShortcutConstants.USER_SHORTCUT_TYPES) {
+ if (IntStream.of(EXPECTED_TYPES_GESTURE).noneMatch(x -> x == type)) {
+ if (AccessibilityTarget.isRecognizedShortcutType(type)) {
+ throw new AssertionError(
+ "Shortcut type " + type + " should not be recognized");
+ }
+ }
+ }
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java b/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
index 928fce9..8bebc62 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
@@ -20,6 +20,8 @@
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER;
import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.google.common.truth.Truth.assertThat;
@@ -99,8 +101,7 @@
public void getShortcutTargets_softwareShortcutNoService_emptyResult() {
assertThat(
ShortcutUtils.getShortcutTargetsFromSettings(
- mContext,
- ShortcutConstants.UserShortcutType.SOFTWARE, mDefaultUserId)
+ mContext, SOFTWARE, mDefaultUserId)
).isEmpty();
}
@@ -114,13 +115,21 @@
}
@Test
+ public void getShortcutTargets_gestureShortcutNoService_emptyResult() {
+ assertThat(
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContext, GESTURE, mDefaultUserId)
+ ).isEmpty();
+ }
+
+ @Test
public void getShortcutTargets_softwareShortcut1Service_return1Service() {
setupShortcutTargets(ONE_COMPONENT, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
setupShortcutTargets(TWO_COMPONENTS, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
assertThat(
ShortcutUtils.getShortcutTargetsFromSettings(
- mContext, ShortcutConstants.UserShortcutType.SOFTWARE,
+ mContext, SOFTWARE,
mDefaultUserId)
).containsExactlyElementsIn(ONE_COMPONENT);
}
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 1a7117e..499caf5 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -29,6 +29,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -83,6 +84,7 @@
private ChoreographerWrapper mChoreographer;
private StatsLogWrapper mStatsLog;
private ArgumentCaptor<OnJankDataListener> mListenerCapture;
+ private SurfaceControl.OnJankDataListenerRegistration mJankStatsRegistration;
private SurfaceControl mSurfaceControl;
private FrameTracker.FrameTrackerListener mTrackerListener;
private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
@@ -107,10 +109,11 @@
mSurfaceControlWrapper = mock(SurfaceControlWrapper.class);
mListenerCapture = ArgumentCaptor.forClass(OnJankDataListener.class);
- doNothing().when(mSurfaceControlWrapper).addJankStatsListener(
+ mJankStatsRegistration = mock(SurfaceControl.OnJankDataListenerRegistration.class);
+ doReturn(mJankStatsRegistration).when(mSurfaceControlWrapper).addJankStatsListener(
mListenerCapture.capture(), any());
- doNothing().when(mSurfaceControlWrapper).removeJankStatsListener(
- mListenerCapture.capture());
+ doNothing().when(mJankStatsRegistration).flush();
+ doNothing().when(mJankStatsRegistration).removeAfter(anyLong());
mChoreographer = mock(ChoreographerWrapper.class);
mStatsLog = mock(StatsLogWrapper.class);
@@ -483,7 +486,7 @@
// an extra frame to trigger finish
sendFrame(tracker, JANK_NONE, 103L);
- verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+ verify(mJankStatsRegistration).removeAfter(anyLong());
verify(mTrackerListener).triggerPerfetto(any());
verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
@@ -520,7 +523,7 @@
// an extra frame to trigger finish
sendFrame(tracker, JANK_NONE, 103L);
- verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+ verify(mJankStatsRegistration).removeAfter(anyLong());
verify(mTrackerListener, never()).triggerPerfetto(any());
verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
@@ -557,7 +560,7 @@
// janky frame, should be ignored, trigger finish
sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 103L);
- verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+ verify(mJankStatsRegistration).removeAfter(anyLong());
verify(mTrackerListener, never()).triggerPerfetto(any());
verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
@@ -589,7 +592,7 @@
tracker.end(FrameTracker.REASON_END_NORMAL);
sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 106L);
sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 107L);
- verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+ verify(mJankStatsRegistration).removeAfter(anyLong());
verify(mTrackerListener).triggerPerfetto(any());
verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
eq(42), /* displayId */
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index 68095e5..5af272c 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -38,6 +38,7 @@
import android.os.HandlerThread;
import android.os.SystemClock;
import android.provider.DeviceConfig;
+import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewAttachTestActivity;
@@ -67,6 +68,7 @@
private View mView;
private Handler mHandler;
private HandlerThread mWorker;
+ private SurfaceControl mSurfaceControl;
@Rule
public ActivityScenarioRule<ViewAttachTestActivity> mRule =
@@ -79,6 +81,9 @@
public void setup() {
mRule.getScenario().onActivity(activity -> mActivity = activity);
mView = mActivity.getWindow().getDecorView();
+ mSurfaceControl = mView.getViewRootImpl().getSurfaceControl();
+ // Set mNativeObject to a non-zero value to make it a valid SurfaceControl.
+ mSurfaceControl.mNativeObject = 1;
assertThat(mView.isAttachedToWindow()).isTrue();
mHandler = spy(new Handler(mActivity.getMainLooper()));
@@ -88,7 +93,7 @@
}
@Test
- public void testBeginEnd() {
+ public void testBeginEnd_inputView() {
InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
FrameTracker tracker = createMockedFrameTracker();
doReturn(tracker).when(monitor).createFrameTracker(any());
@@ -103,6 +108,22 @@
}
@Test
+ public void testBeginEnd_inputSurfaceControl() {
+ InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
+ FrameTracker tracker = createMockedFrameTracker();
+ doReturn(tracker).when(monitor).createFrameTracker(any());
+ doNothing().when(tracker).begin();
+ doReturn(true).when(tracker).end(anyInt());
+
+ // Simulate a trace session and see if begin / end are invoked.
+ assertThat(monitor.begin(mSurfaceControl, mActivity.getApplicationContext(),
+ Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+ verify(tracker).begin();
+ assertThat(monitor.end(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+ verify(tracker).end(REASON_END_NORMAL);
+ }
+
+ @Test
public void testDisabledThroughDeviceConfig() {
InteractionJankMonitor monitor = new InteractionJankMonitor(mWorker);
@@ -183,8 +204,6 @@
doNothing().when(viewRoot).removeSurfaceChangedCallback(any());
SurfaceControlWrapper surfaceControl = mock(SurfaceControlWrapper.class);
- doNothing().when(surfaceControl).addJankStatsListener(any(), any());
- doNothing().when(surfaceControl).removeJankStatsListener(any());
final ChoreographerWrapper choreographer = mock(ChoreographerWrapper.class);
doReturn(SystemClock.elapsedRealtime()).when(choreographer).getVsyncId();
diff --git a/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java b/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java
index 06d888b..7ffc7b2 100644
--- a/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java
@@ -18,7 +18,6 @@
import static com.google.common.truth.Truth.assertThat;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
import android.platform.test.ravenwood.RavenwoodRule;
import androidx.test.filters.SmallTest;
@@ -77,7 +76,6 @@
}
@Test
- @IgnoreUnderRavenwood(reason = "b/321832617")
public void corruptedFile() throws IOException {
// Create an invalid binary XML file to cause IOException: "Unexpected magic number"
try (FileWriter w = new FileWriter(mFile)) {
diff --git a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
index b90480a..92a7d8e 100644
--- a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
@@ -68,6 +68,7 @@
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -316,6 +317,40 @@
assertNotEquals(UserHandle.USER_CURRENT_OR_SELF, LockPatternUtils.USER_REPAIR_MODE);
}
+ @Test
+ public void testWriteRepairModeCredential_mainThread() {
+ createTestLockSettings();
+ var context = InstrumentationRegistry.getTargetContext();
+
+ var future = new CompletableFuture<Exception>();
+ context.getMainThreadHandler().post(() -> {
+ try {
+ mLockPatternUtils.writeRepairModeCredential(USER_ID);
+ future.complete(null);
+ } catch (Exception e) {
+ future.complete(e);
+ }
+ });
+
+ var e = future.join();
+ assertThat(e).isNotNull();
+ assertThat(e.getMessage()).contains("should not be called from the main thread");
+ }
+
+ @Test
+ public void testWriteRepairModeCredential() throws Exception {
+ var ils = createTestLockSettings();
+
+ when(ils.writeRepairModeCredential(USER_ID)).thenReturn(false);
+ assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isFalse();
+
+ when(ils.writeRepairModeCredential(USER_ID)).thenReturn(true);
+ assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isTrue();
+
+ when(ils.writeRepairModeCredential(USER_ID)).thenThrow(new RemoteException());
+ assertThat(mLockPatternUtils.writeRepairModeCredential(USER_ID)).isFalse();
+ }
+
private TestStrongAuthTracker createStrongAuthTracker() {
final Context context = new ContextWrapper(InstrumentationRegistry.getTargetContext());
return new TestStrongAuthTracker(context, Looper.getMainLooper());
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 66b47da..a115c65 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -40,6 +40,7 @@
<permission name="android.permission.MASTER_CLEAR"/>
<permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
<permission name="android.permission.MODIFY_AUDIO_ROUTING" />
+ <permission name="android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED" />
<permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
diff --git a/data/keyboards/Vendor_18d1_Product_4f60.idc b/data/keyboards/Vendor_18d1_Product_4f60.idc
new file mode 100644
index 0000000..b9fd406
--- /dev/null
+++ b/data/keyboards/Vendor_18d1_Product_4f60.idc
@@ -0,0 +1,18 @@
+# Copyright 2024 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.
+
+# Increase palm thresholds, since this touchpad has a tendency to overstate
+# touch sizes.
+gestureProp.Palm_Width = 40.0
+gestureProp.Multiple_Palm_Width = 40.0
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index f9a6caf..612b387 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -17,6 +17,7 @@
package androidx.window.extensions.embedding;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK;
@@ -29,6 +30,7 @@
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishPrimaryWithSecondary;
import static androidx.window.extensions.embedding.SplitContainer.shouldFinishSecondaryWithPrimary;
+import android.annotation.ColorInt;
import android.app.Activity;
import android.app.WindowConfiguration.WindowingMode;
import android.content.Intent;
@@ -391,13 +393,22 @@
if (splitAttributes == null) {
return TaskFragmentAnimationParams.DEFAULT;
}
+ final int animationBackgroundColor = getAnimationBackgroundColor(splitAttributes);
+ TaskFragmentAnimationParams.Builder builder = new TaskFragmentAnimationParams.Builder();
+ if (animationBackgroundColor != DEFAULT_ANIMATION_BACKGROUND_COLOR) {
+ builder.setAnimationBackgroundColor(animationBackgroundColor);
+ }
+ // TODO(b/293658614): Allow setting custom open/close/changeAnimationResId.
+ return builder.build();
+ }
+
+ @ColorInt
+ private static int getAnimationBackgroundColor(@NonNull SplitAttributes splitAttributes) {
+ int animationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR;
final AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
if (animationBackground instanceof AnimationBackground.ColorBackground colorBackground) {
- return new TaskFragmentAnimationParams.Builder()
- .setAnimationBackgroundColor(colorBackground.getColor())
- .build();
- } else {
- return TaskFragmentAnimationParams.DEFAULT;
+ animationBackgroundColor = colorBackground.getColor();
}
+ return animationBackgroundColor;
}
}
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 d0e49d8..eb1fc23 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -20,8 +20,10 @@
import static androidx.window.extensions.embedding.DividerPresenter.getBoundsOffsetForDivider;
import static androidx.window.extensions.embedding.SplitAttributesHelper.isReversedLayout;
+import static androidx.window.extensions.embedding.SplitController.TAG;
import static androidx.window.extensions.embedding.WindowAttributes.DIM_AREA_ON_TASK;
+import android.annotation.AnimRes;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.WindowConfiguration;
@@ -31,9 +33,11 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
+import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.view.View;
@@ -56,6 +60,7 @@
import androidx.window.extensions.layout.WindowLayoutComponentImpl;
import androidx.window.extensions.layout.WindowLayoutInfo;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.window.flags.Flags;
@@ -125,6 +130,16 @@
static final int RESULT_EXPAND_FAILED_NO_TF_INFO = 2;
/**
+ * The key of {@link ActivityStack} alignment relative to its parent container.
+ * <p>
+ * See {@link ContainerPosition} for possible values.
+ * <p>
+ * Note that this constants must align with the definition in WM Jetpack library.
+ */
+ private static final String KEY_ACTIVITY_STACK_ALIGNMENT =
+ "androidx.window.embedding.ActivityStackAlignment";
+
+ /**
* Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
* Activity, Activity, Intent)}
*/
@@ -649,14 +664,114 @@
// TODO(b/243518738): Update to resizeTaskFragment after we migrate WCT#setRelativeBounds
// and WCT#setWindowingMode to take fragmentToken.
resizeTaskFragmentIfRegistered(wct, container, relativeBounds);
- int windowingMode = container.getTaskContainer().getWindowingModeForTaskFragment(
- relativeBounds);
+ final TaskContainer taskContainer = container.getTaskContainer();
+ final int windowingMode = taskContainer.getWindowingModeForTaskFragment(relativeBounds);
updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode);
- // Always use default animation for standalone ActivityStack.
- updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
+ if (container.isOverlay() && isOverlayTransitionSupported()) {
+ // Use the overlay transition for the overlay container if it's supported.
+ final TaskFragmentAnimationParams params = createOverlayAnimationParams(relativeBounds,
+ taskContainer.getBounds(), container);
+ updateAnimationParams(wct, fragmentToken, params);
+ } else {
+ // Otherwise, fallabck to use the default animation params.
+ updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
+ }
setTaskFragmentDimOnTask(wct, fragmentToken, dimOnTask);
}
+ private static boolean isOverlayTransitionSupported() {
+ return Flags.moveAnimationOptionsToChange()
+ && Flags.activityEmbeddingOverlayPresentationFlag();
+ }
+
+ @NonNull
+ private static TaskFragmentAnimationParams createOverlayAnimationParams(
+ @NonNull Rect relativeBounds, @NonNull Rect parentContainerBounds,
+ @NonNull TaskFragmentContainer container) {
+ if (relativeBounds.isEmpty()) {
+ return TaskFragmentAnimationParams.DEFAULT;
+ }
+
+ final int positionFromOptions = container.getLaunchOptions()
+ .getInt(KEY_ACTIVITY_STACK_ALIGNMENT , -1);
+ final int position = positionFromOptions != -1 ? positionFromOptions
+ // Fallback to calculate from bounds if the info can't be retrieved from options.
+ : getOverlayPosition(relativeBounds, parentContainerBounds);
+
+ return new TaskFragmentAnimationParams.Builder()
+ .setOpenAnimationResId(getOpenAnimationResourcesId(position))
+ .setChangeAnimationResId(R.anim.overlay_task_fragment_change)
+ .setCloseAnimationResId(getCloseAnimationResourcesId(position))
+ .build();
+ }
+
+ @VisibleForTesting
+ @ContainerPosition
+ static int getOverlayPosition(
+ @NonNull Rect relativeBounds, @NonNull Rect parentContainerBounds) {
+ final Rect relativeParentBounds = new Rect(parentContainerBounds);
+ relativeParentBounds.offsetTo(0, 0);
+ final int leftMatch = (relativeParentBounds.left == relativeBounds.left) ? 1 : 0;
+ final int topMatch = (relativeParentBounds.top == relativeBounds.top) ? 1 : 0;
+ final int rightMatch = (relativeParentBounds.right == relativeBounds.right) ? 1 : 0;
+ final int bottomMatch = (relativeParentBounds.bottom == relativeBounds.bottom) ? 1 : 0;
+
+ // Flag format: {left|top|right|bottom}. Note that overlay container could be shrunk and
+ // centered, which makes only one of overlay container edge matches the parent container.
+ final int directionFlag = (leftMatch << 3) + (topMatch << 2) + (rightMatch << 1)
+ + bottomMatch;
+
+ final int position = switch (directionFlag) {
+ // Only the left edge match or only the right edge not match: should be on the left of
+ // the parent container.
+ case 0b1000, 0b1101 -> CONTAINER_POSITION_LEFT;
+ // Only the top edge match or only the bottom edge not match: should be on the top of
+ // the parent container.
+ case 0b0100, 0b1110 -> CONTAINER_POSITION_TOP;
+ // Only the right edge match or only the left edge not match: should be on the right of
+ // the parent container.
+ case 0b0010, 0b0111 -> CONTAINER_POSITION_RIGHT;
+ // Only the bottom edge match or only the top edge not match: should be on the bottom of
+ // the parent container.
+ case 0b0001, 0b1011 -> CONTAINER_POSITION_BOTTOM;
+ default -> {
+ Log.w(TAG, "Unsupported position:" + Integer.toBinaryString(directionFlag)
+ + " fallback to treat it as right. Relative parent bounds: "
+ + relativeParentBounds + ", relative overlay bounds:" + relativeBounds);
+ yield CONTAINER_POSITION_RIGHT;
+ }
+ };
+ return position;
+ }
+
+ @AnimRes
+ private static int getOpenAnimationResourcesId(@ContainerPosition int position) {
+ return switch (position) {
+ case CONTAINER_POSITION_LEFT -> R.anim.overlay_task_fragment_open_from_left;
+ case CONTAINER_POSITION_TOP -> R.anim.overlay_task_fragment_open_from_top;
+ case CONTAINER_POSITION_RIGHT -> R.anim.overlay_task_fragment_open_from_right;
+ case CONTAINER_POSITION_BOTTOM -> R.anim.overlay_task_fragment_open_from_bottom;
+ default -> {
+ Log.w(TAG, "Unknown position:" + position);
+ yield Resources.ID_NULL;
+ }
+ };
+ }
+
+ @AnimRes
+ private static int getCloseAnimationResourcesId(@ContainerPosition int position) {
+ return switch (position) {
+ case CONTAINER_POSITION_LEFT -> R.anim.overlay_task_fragment_close_to_left;
+ case CONTAINER_POSITION_TOP -> R.anim.overlay_task_fragment_close_to_top;
+ case CONTAINER_POSITION_RIGHT -> R.anim.overlay_task_fragment_close_to_right;
+ case CONTAINER_POSITION_BOTTOM -> R.anim.overlay_task_fragment_close_to_bottom;
+ default -> {
+ Log.w(TAG, "Unknown position:" + position);
+ yield Resources.ID_NULL;
+ }
+ };
+ }
+
/**
* Returns the expanded bounds if the {@code relBounds} violate minimum dimension or are not
* fully covered by the task bounds. Otherwise, returns {@code relBounds}.
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 7a0b9a0..3257502 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -30,6 +30,11 @@
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitPlaceholderRuleBuilder;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTfContainer;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_TOP;
+import static androidx.window.extensions.embedding.SplitPresenter.getOverlayPosition;
import static androidx.window.extensions.embedding.SplitPresenter.sanitizeBounds;
import static androidx.window.extensions.embedding.WindowAttributes.DIM_AREA_ON_TASK;
@@ -666,8 +671,8 @@
attributes.getRelativeBounds());
verify(mSplitPresenter).updateTaskFragmentWindowingModeIfRegistered(mTransaction, container,
WINDOWING_MODE_MULTI_WINDOW);
- verify(mSplitPresenter).updateAnimationParams(mTransaction, token,
- TaskFragmentAnimationParams.DEFAULT);
+ verify(mSplitPresenter).updateAnimationParams(eq(mTransaction), eq(token),
+ any(TaskFragmentAnimationParams.class));
verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, container, true);
verify(mSplitPresenter, never()).setTaskFragmentPinned(any(),
any(TaskFragmentContainer.class), anyBoolean());
@@ -691,8 +696,8 @@
attributes.getRelativeBounds());
verify(mSplitPresenter).updateTaskFragmentWindowingModeIfRegistered(mTransaction,
container, WINDOWING_MODE_MULTI_WINDOW);
- verify(mSplitPresenter).updateAnimationParams(mTransaction, token,
- TaskFragmentAnimationParams.DEFAULT);
+ verify(mSplitPresenter).updateAnimationParams(eq(mTransaction), eq(token),
+ any(TaskFragmentAnimationParams.class));
verify(mSplitPresenter, never()).setTaskFragmentIsolatedNavigation(any(),
any(TaskFragmentContainer.class), anyBoolean());
verify(mSplitPresenter).setTaskFragmentPinned(mTransaction, container, true);
@@ -870,6 +875,59 @@
eq(overlayContainer.getTaskFragmentToken()), eq(activityToken));
}
+ // TODO(b/243518738): Rewrite with TestParameter.
+ @Test
+ public void testGetOverlayPosition() {
+ assertWithMessage("It must be position left for left overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.left,
+ TASK_BOUNDS.top,
+ TASK_BOUNDS.right / 2,
+ TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_LEFT);
+ assertWithMessage("It must be position left for shrunk left overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.left,
+ TASK_BOUNDS.top + 20,
+ TASK_BOUNDS.right / 2,
+ TASK_BOUNDS.bottom - 20), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_LEFT);
+ assertWithMessage("It must be position left for top overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.left,
+ TASK_BOUNDS.top,
+ TASK_BOUNDS.right,
+ TASK_BOUNDS.bottom / 2), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_TOP);
+ assertWithMessage("It must be position left for shrunk top overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.left + 20,
+ TASK_BOUNDS.top,
+ TASK_BOUNDS.right - 20,
+ TASK_BOUNDS.bottom / 2), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_TOP);
+ assertWithMessage("It must be position left for right overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.right / 2,
+ TASK_BOUNDS.top,
+ TASK_BOUNDS.right,
+ TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_RIGHT);
+ assertWithMessage("It must be position left for shrunk right overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.right / 2,
+ TASK_BOUNDS.top + 20,
+ TASK_BOUNDS.right,
+ TASK_BOUNDS.bottom - 20), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_RIGHT);
+ assertWithMessage("It must be position left for bottom overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.left,
+ TASK_BOUNDS.bottom / 2,
+ TASK_BOUNDS.right,
+ TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_BOTTOM);
+ assertWithMessage("It must be position left for shrunk bottom overlay.")
+ .that(getOverlayPosition(new Rect(
+ TASK_BOUNDS.left + 20,
+ TASK_BOUNDS.bottom / 20,
+ TASK_BOUNDS.right - 20,
+ TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_BOTTOM);
+ }
+
/**
* A simplified version of {@link SplitController#createOrUpdateOverlayTaskFragmentIfNeeded}
*/
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 25d3067..1e68241 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -88,7 +88,7 @@
],
tools: ["protologtool"],
cmd: "$(location protologtool) transform-protolog-calls " +
- "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+ "--protolog-class com.android.internal.protolog.ProtoLog " +
"--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " +
"--loggroups-jar $(location :wm_shell_protolog-groups) " +
"--viewer-config-file-path /system_ext/etc/wmshell.protolog.pb " +
@@ -107,7 +107,7 @@
],
tools: ["protologtool"],
cmd: "$(location protologtool) generate-viewer-config " +
- "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+ "--protolog-class com.android.internal.protolog.ProtoLog " +
"--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " +
"--loggroups-jar $(location :wm_shell_protolog-groups) " +
"--viewer-config-type json " +
@@ -124,7 +124,7 @@
],
tools: ["protologtool"],
cmd: "$(location protologtool) generate-viewer-config " +
- "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+ "--protolog-class com.android.internal.protolog.ProtoLog " +
"--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " +
"--loggroups-jar $(location :wm_shell_protolog-groups) " +
"--viewer-config-type proto " +
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 3b7eb29..3ff40e0 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -131,3 +131,10 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "enable_bubble_bar_in_persistent_task_bar"
+ namespace: "multitasking"
+ description: "Enable bubble bar to be shown in the persistent task bar"
+ bug: "346391377"
+}
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/OWNERS b/libs/WindowManager/Shell/multivalentScreenshotTests/OWNERS
new file mode 100644
index 0000000..dc11241
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/OWNERS
@@ -0,0 +1,4 @@
+atsjenk@google.com
+liranb@google.com
+madym@google.com
+mpodolian@google.com
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/dark_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/dark_portrait_bubbles_education.png
index eb28881..027b28e 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/dark_portrait_bubbles_education.png
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/dark_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/light_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/light_portrait_bubbles_education.png
index eb28881..027b28e 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/light_portrait_bubbles_education.png
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/light_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
index 9e1440d..ae60d8b 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
@@ -27,7 +27,7 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.R
import com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT
import com.android.wm.shell.common.bubbles.BubbleBarLocation
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
index 327e205..5e67333 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
@@ -32,7 +32,7 @@
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.launcher3.icons.BubbleIconFactory
import com.android.wm.shell.Flags
import com.android.wm.shell.R
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
index ace2c13..935d129 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
@@ -27,7 +27,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.R
import com.android.wm.shell.bubbles.BubblePositioner
import com.android.wm.shell.bubbles.DeviceConfig
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
index 7d5f9cd..5fe3f2a 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
@@ -14,88 +14,100 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/maximize_menu"
- style="?android:attr/buttonBarStyle"
android:layout_width="@dimen/desktop_mode_maximize_menu_width"
android:layout_height="@dimen/desktop_mode_maximize_menu_height"
- android:orientation="horizontal"
- android:gravity="center"
- android:padding="16dp"
android:background="@drawable/desktop_mode_maximize_menu_background"
android:elevation="1dp">
<LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:id="@+id/container"
+ android:layout_width="@dimen/desktop_mode_maximize_menu_width"
+ android:layout_height="@dimen/desktop_mode_maximize_menu_height"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:gravity="center">
- <Button
- android:layout_width="94dp"
- android:layout_height="60dp"
- android:id="@+id/maximize_menu_maximize_button"
- style="?android:attr/buttonBarButtonStyle"
- android:stateListAnimator="@null"
- android:layout_marginRight="8dp"
- android:layout_marginBottom="4dp"
- android:alpha="0"/>
-
- <TextView
- android:id="@+id/maximize_menu_maximize_window_text"
- android:layout_width="94dp"
- android:layout_height="18dp"
- android:textSize="11sp"
- android:layout_marginBottom="76dp"
- android:gravity="center"
- android:fontFamily="google-sans-text"
- android:text="@string/desktop_mode_maximize_menu_maximize_text"
- android:textColor="?androidprv:attr/materialColorOnSurface"
- android:alpha="0"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical">
<LinearLayout
- android:id="@+id/maximize_menu_snap_menu_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:padding="4dp"
- android:background="@drawable/desktop_mode_maximize_menu_layout_background"
- android:layout_marginBottom="4dp"
- android:alpha="0">
- <Button
- android:id="@+id/maximize_menu_snap_left_button"
- style="?android:attr/buttonBarButtonStyle"
- android:layout_width="41dp"
- android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
- android:layout_marginRight="4dp"
- android:background="@drawable/desktop_mode_maximize_menu_button_background"
- android:stateListAnimator="@null"/>
+ android:orientation="vertical">
<Button
- android:id="@+id/maximize_menu_snap_right_button"
+ android:layout_width="94dp"
+ android:layout_height="60dp"
+ android:id="@+id/maximize_menu_maximize_button"
style="?android:attr/buttonBarButtonStyle"
- android:layout_width="41dp"
- android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
- android:background="@drawable/desktop_mode_maximize_menu_button_background"
- android:stateListAnimator="@null"/>
+ android:stateListAnimator="@null"
+ android:layout_marginRight="8dp"
+ android:layout_marginBottom="4dp"
+ android:alpha="0"/>
+
+ <TextView
+ android:id="@+id/maximize_menu_maximize_window_text"
+ android:layout_width="94dp"
+ android:layout_height="18dp"
+ android:textSize="11sp"
+ android:layout_marginBottom="76dp"
+ android:gravity="center"
+ android:fontFamily="google-sans-text"
+ android:text="@string/desktop_mode_maximize_menu_maximize_text"
+ android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:alpha="0"/>
</LinearLayout>
- <TextView
- android:id="@+id/maximize_menu_snap_window_text"
- android:layout_width="94dp"
- android:layout_height="18dp"
- android:textSize="11sp"
- android:layout_marginBottom="76dp"
- android:layout_gravity="center"
- android:gravity="center"
- android:fontFamily="google-sans-text"
- android:text="@string/desktop_mode_maximize_menu_snap_text"
- android:textColor="?androidprv:attr/materialColorOnSurface"
- android:alpha="0"/>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <LinearLayout
+ android:id="@+id/maximize_menu_snap_menu_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="4dp"
+ android:background="@drawable/desktop_mode_maximize_menu_layout_background"
+ android:layout_marginBottom="4dp"
+ android:alpha="0">
+ <Button
+ android:id="@+id/maximize_menu_snap_left_button"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="41dp"
+ android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
+ android:layout_marginRight="4dp"
+ android:background="@drawable/desktop_mode_maximize_menu_button_background"
+ android:stateListAnimator="@null"/>
+
+ <Button
+ android:id="@+id/maximize_menu_snap_right_button"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="41dp"
+ android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
+ android:background="@drawable/desktop_mode_maximize_menu_button_background"
+ android:stateListAnimator="@null"/>
+ </LinearLayout>
+ <TextView
+ android:id="@+id/maximize_menu_snap_window_text"
+ android:layout_width="94dp"
+ android:layout_height="18dp"
+ android:textSize="11sp"
+ android:layout_marginBottom="76dp"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:fontFamily="google-sans-text"
+ android:text="@string/desktop_mode_maximize_menu_snap_text"
+ android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:alpha="0"/>
+ </LinearLayout>
</LinearLayout>
-</LinearLayout>
+
+ <!-- Empty view intentionally placed in front of everything else and matching the menu size
+ used to monitor input events over the entire menu. -->
+ <View
+ android:id="@+id/maximize_menu_overlay"
+ android:layout_width="@dimen/desktop_mode_maximize_menu_width"
+ android:layout_height="@dimen/desktop_mode_maximize_menu_height"/>
+</FrameLayout>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index e537f0a..d7e23fd 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubbles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Show Bubbles"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index bdcd275..1da8c27 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -84,10 +84,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
- <skip />
- <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
- <skip />
+ <string name="bubble_shortcut_label" msgid="666269077944378311">"Bubbles"</string>
+ <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Show Bubbles"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 3910042..4b9be47 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -53,7 +53,7 @@
<string name="accessibility_split_top" msgid="2789329702027147146">"تقسیم از بالا"</string>
<string name="accessibility_split_bottom" msgid="8694551025220868191">"تقسیم از پایین"</string>
<string name="one_handed_tutorial_title" msgid="4583241688067426350">"استفاده از حالت یکدستی"</string>
- <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحهنمایش تند بهطرف بالا بکشید یا در هر جایی از بالای برنامه که میخواهید ضربه بزنید"</string>
+ <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحهنمایش تند بهطرف بالا بکشید یا در هر جایی از بالای برنامه که میخواهید تکضرب بزنید"</string>
<string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"آغاز «حالت یکدستی»"</string>
<string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"خروج از «حالت یکدستی»"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"تنظیمات برای حبابکهای <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -71,16 +71,16 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"رد کردن حبابک"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"مکالمه در حباب نشان داده نشود"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"گپ بااستفاده از حبابکها"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"مکالمههای جدید بهصورت نمادهای شناور یا حبابکها نشان داده میشوند. برای باز کردن حبابکها ضربه بزنید. برای جابهجایی، آن را بکشید."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"مکالمههای جدید بهصورت نمادهای شناور یا حبابکها نشان داده میشوند. برای باز کردن حبابکها تکضرب بزنید. برای جابهجایی، آن را بکشید."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"کنترل حبابکها در هرزمانی"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"برای خاموش کردن حبابکها از این برنامه، روی «مدیریت» ضربه بزنید"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"برای خاموش کردن حبابکها از این برنامه، روی «مدیریت» تکضرب بزنید"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"متوجهام"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"هیچ حبابک جدیدی وجود ندارد"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حبابکهای اخیر و حبابکهای ردشده اینجا ظاهر خواهند شد"</string>
<string name="bubble_bar_education_stack_title" msgid="2486903590422497245">"گپ زدن بااستفاده از حبابک"</string>
- <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"مکالمههای جدید بهصورت نماد در گوشه پایین صفحهنمایش نشان داده میشود. برای ازهم بازکردن آنها ضربه بزنید یا برای بستن، آنها را بکشید."</string>
+ <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"مکالمههای جدید بهصورت نماد در گوشه پایین صفحهنمایش نشان داده میشود. برای ازهم بازکردن آنها تکضرب بزنید یا برای بستن، آنها را بکشید."</string>
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"کنترل حبابکها در هرزمانی"</string>
- <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"برای مدیریت اینکه کدام برنامهها و مکالمهها حباب داشته باشند، ضربه بزنید"</string>
+ <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"برای مدیریت اینکه کدام برنامهها و مکالمهها حباب داشته باشند، تکضرب بزنید"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string>
@@ -88,12 +88,12 @@
<skip />
<!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
<skip />
- <string name="restart_button_description" msgid="4564728020654658478">"برای داشتن نمایی بهتر، ضربه بزنید تا این برنامه بازراهاندازی شود"</string>
+ <string name="restart_button_description" msgid="4564728020654658478">"برای داشتن نمایی بهتر، تکضرب بزنید تا این برنامه بازراهاندازی شود"</string>
<string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"نسبت ابعادی این برنامه را در «تنظیمات» تغییر دهید"</string>
<string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"تغییر نسبت ابعادی"</string>
- <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"دوربین مشکل دارد؟\nبرای تنظیم مجدد اندازه ضربه بزنید"</string>
- <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن ضربه بزنید"</string>
- <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن ضربه بزنید."</string>
+ <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"دوربین مشکل دارد؟\nبرای تنظیم مجدد اندازه تکضرب بزنید"</string>
+ <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن تکضرب بزنید"</string>
+ <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن تکضرب بزنید."</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"از چندین برنامه بهطور همزمان استفاده کنید"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"برای حالت صفحهٔ دونیمه، در برنامهای دیگر بکشید"</string>
<string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابهجا کردن برنامه، بیرون از آن دوضربه بزنید"</string>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java
index 4876f32..92084e4 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java
@@ -16,9 +16,13 @@
package com.android.wm.shell.shared;
+import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES;
+
import android.annotation.NonNull;
import android.content.Context;
import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -29,6 +33,8 @@
*/
public class DesktopModeStatus {
+ private static final String TAG = "DesktopModeStatus";
+
/**
* Flag to indicate whether task resizing is veiled.
*/
@@ -98,11 +104,12 @@
"persist.wm.debug.desktop_max_task_limit", DEFAULT_MAX_TASK_LIMIT);
/**
- * Return {@code true} if desktop windowing is enabled. Only to be used for testing. Callers
- * should use {@link #canEnterDesktopMode(Context)} to query the state of desktop windowing.
+ * Return {@code true} if desktop windowing flag is enabled. Only to be used for testing.
+ * Callers should use {@link #canEnterDesktopMode(Context)} to query the state of desktop
+ * windowing.
*/
@VisibleForTesting
- public static boolean isEnabled() {
+ public static boolean isDesktopModeFlagEnabled() {
return Flags.enableDesktopWindowingMode();
}
@@ -120,7 +127,7 @@
*/
public static boolean useWindowShadow(boolean isFocusedWindow) {
return USE_WINDOW_SHADOWS
- || (USE_WINDOW_SHADOWS_FOCUSED_WINDOW && isFocusedWindow);
+ || (USE_WINDOW_SHADOWS_FOCUSED_WINDOW && isFocusedWindow);
}
/**
@@ -154,10 +161,36 @@
}
/**
+ * Return {@code true} if desktop mode dev option should be shown on current device
+ */
+ public static boolean canShowDesktopModeDevOption(@NonNull Context context) {
+ return isDeviceEligibleForDesktopMode(context) && Flags.showDesktopWindowingDevOption();
+ }
+
+ /** Returns if desktop mode dev option should be enabled if there is no user override. */
+ public static boolean shouldDevOptionBeEnabledByDefault() {
+ return isDesktopModeFlagEnabled();
+ }
+
+ /**
* Return {@code true} if desktop mode is enabled and can be entered on the current device.
*/
public static boolean canEnterDesktopMode(@NonNull Context context) {
- return (!enforceDeviceRestrictions() || isDesktopModeSupported(context)) && isEnabled();
+ if (!isDeviceEligibleForDesktopMode(context)) return false;
+
+ // If dev option has ever been manually toggled by the user, return its value
+ // TODO(b/348193756) : Move the logic for DW override based on toggle overides to a common
+ // infrastructure and add caching for the computation
+ int defaultOverrideState = -1;
+ int toggleState = Settings.Global.getInt(context.getContentResolver(),
+ DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, defaultOverrideState);
+ if (toggleState != defaultOverrideState) {
+ Log.d(TAG, "Using Desktop mode dev option overridden state");
+ return toggleState != 0;
+ }
+
+ // Return Desktop windowing flag value
+ return isDesktopModeFlagEnabled();
}
/**
@@ -181,4 +214,11 @@
return DESKTOP_DENSITY_OVERRIDE >= DESKTOP_DENSITY_MIN
&& DESKTOP_DENSITY_OVERRIDE <= DESKTOP_DENSITY_MAX;
}
+
+ /**
+ * Return {@code true} if desktop mode is unrestricted and is supported in the device.
+ */
+ private static boolean isDeviceEligibleForDesktopMode(@NonNull Context context) {
+ return !enforceDeviceRestrictions() || isDesktopModeSupported(context);
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
index ef9bf00..514307f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
@@ -19,7 +19,7 @@
import com.android.internal.protolog.LegacyProtoLogImpl;
import com.android.internal.protolog.common.ILogger;
import com.android.internal.protolog.common.IProtoLog;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellInit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
index 2e5448a..b9bf136 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
@@ -29,7 +29,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.sysui.ShellInit;
import java.io.PrintWriter;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
index 5143d41..9f01316 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
@@ -38,7 +38,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.sysui.ShellInit;
import java.io.PrintWriter;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 3ded7d2..ebdea1b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -52,7 +52,7 @@
import android.window.TaskOrganizer;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
import com.android.wm.shell.common.ScreenshotUtils;
import com.android.wm.shell.common.ShellExecutor;
@@ -124,6 +124,15 @@
}
/**
+ * Limited scope callback to notify when a task is removed from the system. This signal is
+ * not synchronized with anything (or any transition), and should not be used in cases where
+ * that is necessary.
+ */
+ public interface TaskVanishedListener {
+ default void onTaskVanished(RunningTaskInfo taskInfo) {}
+ }
+
+ /**
* Callbacks for events on a task with a locus id.
*/
public interface LocusIdListener {
@@ -167,6 +176,9 @@
private final ArraySet<FocusListener> mFocusListeners = new ArraySet<>();
+ // Listeners that should be notified when a task is removed
+ private final ArraySet<TaskVanishedListener> mTaskVanishedListeners = new ArraySet<>();
+
private final Object mLock = new Object();
private StartingWindowController mStartingWindow;
@@ -409,7 +421,7 @@
}
/**
- * Removes listener.
+ * Removes a locus id listener.
*/
public void removeLocusIdListener(LocusIdListener listener) {
synchronized (mLock) {
@@ -430,7 +442,7 @@
}
/**
- * Removes listener.
+ * Removes a focus listener.
*/
public void removeFocusListener(FocusListener listener) {
synchronized (mLock) {
@@ -439,6 +451,24 @@
}
/**
+ * Adds a listener to be notified when a task vanishes.
+ */
+ public void addTaskVanishedListener(TaskVanishedListener listener) {
+ synchronized (mLock) {
+ mTaskVanishedListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a task-vanished listener.
+ */
+ public void removeTaskVanishedListener(TaskVanishedListener listener) {
+ synchronized (mLock) {
+ mTaskVanishedListeners.remove(listener);
+ }
+ }
+
+ /**
* Returns a surface which can be used to attach overlays to the home root task
*/
@NonNull
@@ -614,6 +644,9 @@
t.apply();
ProtoLog.v(WM_SHELL_TASK_ORG, "Removing overlay surface");
}
+ for (TaskVanishedListener l : mTaskVanishedListeners) {
+ l.onTaskVanished(taskInfo);
+ }
if (!ENABLE_SHELL_TRANSITIONS && (appearedInfo.getLeash() != null)) {
// Preemptively clean up the leash only if shell transitions are not enabled
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 5a42817..d270d2b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -265,7 +265,7 @@
for (TransitionInfo.Change change : openingChanges) {
final Animation animation =
animationProvider.get(info, change, openingWholeScreenBounds);
- if (animation.getDuration() == 0) {
+ if (shouldUseJumpCutForAnimation(animation)) {
continue;
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
@@ -290,7 +290,7 @@
}
final Animation animation =
animationProvider.get(info, change, closingWholeScreenBounds);
- if (animation.getDuration() == 0) {
+ if (shouldUseJumpCutForAnimation(animation)) {
continue;
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
@@ -444,8 +444,16 @@
calculateParentBounds(change, boundsAnimationChange, parentBounds);
// There are two animations in the array. The first one is for the start leash
// (snapshot), and the second one is for the end leash (TaskFragment).
- final Animation[] animations = mAnimationSpec.createChangeBoundsChangeAnimations(change,
- parentBounds);
+ final Animation[] animations =
+ mAnimationSpec.createChangeBoundsChangeAnimations(info, change, parentBounds);
+ // Jump cut if either animation has zero for duration.
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ for (Animation animation : animations) {
+ if (shouldUseJumpCutForAnimation(animation)) {
+ return new ArrayList<>();
+ }
+ }
+ }
// Keep track as we might need to add background color for the animation.
// Although there may be multiple change animation, record one of them is sufficient
// because the background color will be added to the root leash for the whole animation.
@@ -492,12 +500,19 @@
// window without bounds change.
animation = ActivityEmbeddingAnimationSpec.createNoopAnimation(change);
} else if (TransitionUtil.isClosingType(change.getMode())) {
- animation = mAnimationSpec.createChangeBoundsCloseAnimation(change, parentBounds);
+ animation =
+ mAnimationSpec.createChangeBoundsCloseAnimation(info, change, parentBounds);
shouldShowBackgroundColor = false;
} else {
- animation = mAnimationSpec.createChangeBoundsOpenAnimation(change, parentBounds);
+ animation =
+ mAnimationSpec.createChangeBoundsOpenAnimation(info, change, parentBounds);
shouldShowBackgroundColor = false;
}
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ if (shouldUseJumpCutForAnimation(animation)) {
+ return new ArrayList<>();
+ }
+ }
adapters.add(new ActivityEmbeddingAnimationAdapter(animation, change,
TransitionUtil.getRootFor(change, info)));
}
@@ -640,6 +655,12 @@
return true;
}
+ /** Whether or not to use jump cut based on the animation. */
+ @VisibleForTesting
+ static boolean shouldUseJumpCutForAnimation(@NonNull Animation animation) {
+ return animation.getDuration() == 0;
+ }
+
/** Updates the changes to end states in {@code startTransaction} for jump cut animation. */
private void prepareForJumpCut(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index 8d49614..f49b90d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -46,7 +46,6 @@
import com.android.wm.shell.shared.TransitionUtil;
/** Animation spec for ActivityEmbedding transition. */
-// TODO(b/206557124): provide an easier way to customize animation
class ActivityEmbeddingAnimationSpec {
private static final String TAG = "ActivityEmbeddingAnimSpec";
@@ -95,8 +94,14 @@
/** Animation for window that is opening in a change transition. */
@NonNull
- Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo.Change change,
- @NonNull Rect parentBounds) {
+ Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ final Animation customAnimation = loadCustomAnimation(info, change);
+ if (customAnimation != null) {
+ return customAnimation;
+ }
+ }
// Use end bounds for opening.
final Rect bounds = change.getEndAbsBounds();
final int startLeft;
@@ -123,8 +128,14 @@
/** Animation for window that is closing in a change transition. */
@NonNull
- Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo.Change change,
- @NonNull Rect parentBounds) {
+ Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ final Animation customAnimation = loadCustomAnimation(info, change);
+ if (customAnimation != null) {
+ return customAnimation;
+ }
+ }
// Use start bounds for closing.
final Rect bounds = change.getStartAbsBounds();
final int endTop;
@@ -155,8 +166,17 @@
* the second one is for the end leash.
*/
@NonNull
- Animation[] createChangeBoundsChangeAnimations(@NonNull TransitionInfo.Change change,
- @NonNull Rect parentBounds) {
+ Animation[] createChangeBoundsChangeAnimations(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
+ if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+ // TODO(b/293658614): Support more complicated animations that may need more than a noop
+ // animation as the start leash.
+ final Animation noopAnimation = createNoopAnimation(change);
+ final Animation customAnimation = loadCustomAnimation(info, change);
+ if (customAnimation != null) {
+ return new Animation[]{noopAnimation, customAnimation};
+ }
+ }
// Both start bounds and end bounds are in screen coordinates. We will post translate
// to the local coordinates in ActivityEmbeddingAnimationAdapter#onAnimationUpdate
final Rect startBounds = change.getStartAbsBounds();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 7041ea3..ece0271 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -59,7 +59,7 @@
import android.window.IOnBackInvokedCallback;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.LatencyTracker;
import com.android.internal.view.AppearanceRegion;
import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index 4988a94..e24df0b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -30,7 +30,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.Cuj.CujType;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
+import com.android.internal.jank.InteractionJankMonitor;
/**
* Used to register the animation callback and runner, it will trigger result if gesture was finish
@@ -86,20 +86,21 @@
*/
void startAnimation(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps, Runnable finishedCallback) {
+ InteractionJankMonitor interactionJankMonitor = InteractionJankMonitor.getInstance();
final IRemoteAnimationFinishedCallback callback =
new IRemoteAnimationFinishedCallback.Stub() {
@Override
public void onAnimationFinished() {
if (shouldMonitorCUJ(apps)) {
- InteractionJankMonitorUtils.endTracing(mCujType);
+ interactionJankMonitor.end(mCujType);
}
finishedCallback.run();
}
};
mWaitingAnimation = false;
if (shouldMonitorCUJ(apps)) {
- InteractionJankMonitorUtils.beginTracing(
- mCujType, mContext, apps[0].leash, /* tag */ null);
+ interactionJankMonitor.begin(
+ apps[0].leash, mContext, mCujType);
}
try {
getRunner().onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index c9d3dbd..4f04c5c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -48,7 +48,7 @@
import com.android.internal.jank.Cuj
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.internal.policy.SystemBarUtils
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.animation.Interpolators
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index 381914a5..103a654 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -49,7 +49,7 @@
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.policy.SystemBarUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.shared.annotations.ShellMainThread;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
index c738ce5..e266e2c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
@@ -28,7 +28,7 @@
import android.window.BackNavigationInfo
import com.android.internal.R
import com.android.internal.policy.TransitionAnimation
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup
import com.android.wm.shell.shared.annotations.ShellMainThread
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 2aefc64..7dbbb04 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
@@ -48,7 +48,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.BubbleIconFactory;
import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView;
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index c853301..e36f6e6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -84,7 +84,7 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.CollectionUtils;
import com.android.launcher3.icons.BubbleIconFactory;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 761e025..4e6c517 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -35,7 +35,7 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
import com.android.wm.shell.R;
import com.android.wm.shell.bubbles.Bubbles.DismissReason;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index c7ccd50..f7a5c27 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -67,7 +67,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.common.AlphaOptimizedButton;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index 18e04d1..bf98ef8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -42,7 +42,7 @@
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ContrastColorUtil;
import com.android.wm.shell.Flags;
import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 2382545..0cf187b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -29,7 +29,7 @@
import androidx.annotation.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconNormalizer;
import com.android.wm.shell.R;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 09bec8c..f93f19d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -78,7 +78,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
import com.android.wm.shell.Flags;
import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
index 0b66bcb..c79d9c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
@@ -35,7 +35,7 @@
import androidx.annotation.Nullable;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.taskview.TaskView;
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
index 1375684..9429c9e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
@@ -29,7 +29,7 @@
import androidx.annotation.Nullable;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.bubbles.BubblesNavBarMotionEventHandler.MotionEventListener;
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
index b7107f0..d4f53ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
@@ -28,7 +28,7 @@
import androidx.annotation.Nullable;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
/**
* Handles {@link MotionEvent}s for bubbles that begin in the nav bar area
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
index aa4129a..fbef6b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
@@ -38,7 +38,7 @@
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.bubbles.BubbleExpandedView;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
deleted file mode 100644
index 86f00b8..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.SurfaceControl;
-import android.view.View;
-
-import com.android.internal.jank.Cuj.CujType;
-import com.android.internal.jank.InteractionJankMonitor;
-
-/** Utils class for simplfy InteractionJank trancing call */
-public class InteractionJankMonitorUtils {
-
- /**
- * Begin a trace session.
- *
- * @param cujType the specific {@link CujType}.
- * @param view the view to trace
- * @param tag the tag to distinguish different flow of same type CUJ.
- */
- public static void beginTracing(@CujType int cujType,
- @NonNull View view, @Nullable String tag) {
- final InteractionJankMonitor.Configuration.Builder builder =
- InteractionJankMonitor.Configuration.Builder.withView(cujType, view);
- if (!TextUtils.isEmpty(tag)) {
- builder.setTag(tag);
- }
- InteractionJankMonitor.getInstance().begin(builder);
- }
-
- /**
- * Begin a trace session.
- *
- * @param cujType the specific {@link CujType}.
- * @param context the context
- * @param surface the surface to trace
- * @param tag the tag to distinguish different flow of same type CUJ.
- */
- public static void beginTracing(@CujType int cujType,
- @NonNull Context context, @NonNull SurfaceControl surface, @Nullable String tag) {
- final InteractionJankMonitor.Configuration.Builder builder =
- InteractionJankMonitor.Configuration.Builder.withSurface(cujType, context, surface);
- if (!TextUtils.isEmpty(tag)) {
- builder.setTag(tag);
- }
- InteractionJankMonitor.getInstance().begin(builder);
- }
-
- /**
- * End a trace session.
- *
- * @param cujType the specific {@link CujType}.
- */
- public static void endTracing(@CujType int cujType) {
- InteractionJankMonitor.getInstance().end(cujType);
- }
-
- /**
- * Cancel the trace session.
- *
- * @param cujType the specific {@link CujType}.
- */
- public static void cancelTracing(@CujType int cujType) {
- InteractionJankMonitor.getInstance().cancel(cujType);
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
index e261d92..f792392 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
@@ -28,7 +28,7 @@
import android.window.WindowContainerTransactionCallback;
import android.window.WindowOrganizer;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.transition.LegacyTransitions;
import java.util.ArrayList;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
index 43c92ca..43f9cb98 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
@@ -32,7 +32,7 @@
import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.sysui.ShellInit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
index 58007b5..8e026f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
@@ -27,7 +27,7 @@
import android.util.Size;
import android.view.Gravity;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
index 7ceaaea..64a1b0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
@@ -32,7 +32,7 @@
import android.util.Size;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java
index c421dec..b9c698e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java
@@ -26,7 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.shared.annotations.ShellMainThread;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
index 3e9366f..dcf84d9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
@@ -30,7 +30,7 @@
import android.util.Pair
import android.util.TypedValue
import android.window.TaskSnapshot
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.Flags
import com.android.wm.shell.protolog.ShellProtoLogGroup
import kotlin.math.abs
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 2234041..3ad60e7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -54,7 +54,7 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index de016d3..5097ed8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -269,7 +269,9 @@
if (update) {
if (immediately) {
+ t.setAlpha(mBackgroundLeash, showVeil ? 1f : 0f);
t.setVisibility(mBackgroundLeash, showVeil);
+ t.setAlpha(mIconLeash, showVeil ? 1f : 0f);
t.setVisibility(mIconLeash, showVeil);
} else {
startFadeAnimation(showVeil, false, null);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 8ced76f..bdef4f4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -59,7 +59,8 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.animation.Interpolators;
@@ -67,7 +68,6 @@
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
@@ -131,6 +131,7 @@
private final boolean mDimNonImeSide;
private final boolean mAllowLeftRightSplitInPortrait;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private boolean mIsLeftRightSplit;
private ValueAnimator mDividerFlingAnimator;
@@ -163,6 +164,7 @@
mRootBounds.set(configuration.windowConfiguration.getBounds());
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+ mInteractionJankMonitor = InteractionJankMonitor.getInstance();
resetDividerPosition();
updateInvisibleRect();
}
@@ -569,12 +571,11 @@
}
void onStartDragging() {
- InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_RESIZE, mContext,
- getDividerLeash(), null /* tag */);
+ mInteractionJankMonitor.begin(getDividerLeash(), mContext, CUJ_SPLIT_SCREEN_RESIZE);
}
void onDraggingCancelled() {
- InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_RESIZE);
+ mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_RESIZE);
}
void onDoubleTappedDivider() {
@@ -638,7 +639,7 @@
if (flingFinishedCallback != null) {
flingFinishedCallback.run();
}
- InteractionJankMonitorUtils.endTracing(
+ mInteractionJankMonitor.end(
CUJ_SPLIT_SCREEN_RESIZE);
return;
}
@@ -661,7 +662,7 @@
if (flingFinishedCallback != null) {
flingFinishedCallback.run();
}
- InteractionJankMonitorUtils.endTracing(
+ mInteractionJankMonitor.end(
CUJ_SPLIT_SCREEN_RESIZE);
mDividerFlingAnimator = null;
}
@@ -707,8 +708,8 @@
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER,
- mContext, getDividerLeash(), null /*tag*/);
+ mInteractionJankMonitor.begin(getDividerLeash(),
+ mContext, CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
}
@Override
@@ -716,12 +717,12 @@
mDividerPosition = dividerPos;
updateBounds(mDividerPosition);
finishCallback.accept(insets);
- InteractionJankMonitorUtils.endTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
+ mInteractionJankMonitor.end(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
}
@Override
public void onAnimationCancel(Animator animation) {
- InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
+ mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
}
});
set.start();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index bfac24b..2520c25 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -258,9 +258,15 @@
return;
}
// We're showing the first reachability education so we ignore incoming TaskInfo
- // until the education flow has completed or we double tap.
+ // until the education flow has completed or we double tap. The double-tap
+ // basically cancel all the onboarding flow. We don't have to ignore events in case
+ // the app is in size compat mode.
if (mIsFirstReachabilityEducationRunning) {
- return;
+ if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap
+ && !taskInfo.appCompatTaskInfo.topActivityInSizeCompat) {
+ return;
+ }
+ mIsFirstReachabilityEducationRunning = false;
}
if (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed) {
if (taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled) {
@@ -278,17 +284,24 @@
final boolean isFirstTimeVerticalReachabilityEdu = !topActivityPillarboxed
&& !mCompatUIConfiguration.hasSeenVerticalReachabilityEducation(taskInfo);
if (isFirstTimeHorizontalReachabilityEdu || isFirstTimeVerticalReachabilityEdu) {
- mIsFirstReachabilityEducationRunning = true;
mCompatUIConfiguration.setSeenLetterboxEducation(taskInfo.userId);
- createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
- return;
+ // We activate the first reachability education if the double-tap is enabled.
+ // If the double tap is not enabled (e.g. thin letterbox) we just set the value
+ // of the education being seen.
+ if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
+ mIsFirstReachabilityEducationRunning = true;
+ createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
+ return;
+ }
}
}
}
createOrUpdateCompatLayout(taskInfo, taskListener);
createOrUpdateRestartDialogLayout(taskInfo, taskListener);
if (mCompatUIConfiguration.getHasSeenLetterboxEducation(taskInfo.userId)) {
- createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
+ if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
+ createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
+ }
// The user aspect ratio button should not be handled when a new TaskInfo is
// sent because of a double tap or when in multi-window mode.
if (taskInfo.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 1fcfa7f..da1d6da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.dagger;
import android.annotation.Nullable;
+import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.os.Handler;
@@ -221,7 +222,8 @@
SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopTasksController> desktopTasksController,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ InteractionJankMonitor interactionJankMonitor) {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return new DesktopModeWindowDecorViewModel(
context,
@@ -238,7 +240,8 @@
syncQueue,
transitions,
desktopTasksController,
- rootTaskDisplayAreaOrganizer);
+ rootTaskDisplayAreaOrganizer,
+ interactionJankMonitor);
}
return new CaptionWindowDecorViewModel(
context,
@@ -514,6 +517,7 @@
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
DragAndDropController dragAndDropController,
Transitions transitions,
+ KeyguardManager keyguardManager,
EnterDesktopTaskTransitionHandler enterDesktopTransitionHandler,
ExitDesktopTaskTransitionHandler exitDesktopTransitionHandler,
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
@@ -528,7 +532,7 @@
Optional<RecentTasksController> recentTasksController) {
return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController,
displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
- dragAndDropController, transitions, enterDesktopTransitionHandler,
+ dragAndDropController, transitions, keyguardManager, enterDesktopTransitionHandler,
exitDesktopTransitionHandler, toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler, desktopModeTaskRepository,
desktopModeLoggerTransitionObserver, launchAdjacentController,
@@ -575,8 +579,8 @@
@WMSingleton
@Provides
static ToggleResizeDesktopTaskTransitionHandler provideToggleResizeDesktopTaskTransitionHandler(
- Transitions transitions) {
- return new ToggleResizeDesktopTaskTransitionHandler(transitions);
+ Transitions transitions, InteractionJankMonitor interactionJankMonitor) {
+ return new ToggleResizeDesktopTaskTransitionHandler(transitions, interactionJankMonitor);
}
@WMSingleton
@@ -644,6 +648,7 @@
ShellInit shellInit,
ShellController shellController,
ShellCommandHandler shellCommandHandler,
+ ShellTaskOrganizer shellTaskOrganizer,
DisplayController displayController,
UiEventLogger uiEventLogger,
IconProvider iconProvider,
@@ -651,8 +656,8 @@
Transitions transitions,
@ShellMainThread ShellExecutor mainExecutor) {
return new DragAndDropController(context, shellInit, shellController, shellCommandHandler,
- displayController, uiEventLogger, iconProvider, globalDragListener, transitions,
- mainExecutor);
+ shellTaskOrganizer, displayController, uiEventLogger, iconProvider,
+ globalDragListener, transitions, mainExecutor);
}
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
index 677fd5d..240cf3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
@@ -212,12 +212,13 @@
@WMSingleton
@Provides
static PipMotionHelper providePipMotionHelper(Context context,
+ @ShellMainThread ShellExecutor mainExecutor,
PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer,
PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm,
PipTransitionController pipTransitionController,
FloatingContentCoordinator floatingContentCoordinator,
Optional<PipPerfHintController> pipPerfHintControllerOptional) {
- return new PipMotionHelper(context, pipBoundsState, pipTaskOrganizer,
+ return new PipMotionHelper(context, mainExecutor, pipBoundsState, pipTaskOrganizer,
menuController, pipSnapAlgorithm, pipTransitionController,
floatingContentCoordinator, pipPerfHintControllerOptional);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index e710560..a67dee3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -35,7 +35,7 @@
import androidx.core.util.putAll
import com.android.internal.logging.InstanceId
import com.android.internal.logging.InstanceIdSequence
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index 217b1d3..1bf1259 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -19,6 +19,8 @@
package com.android.wm.shell.desktopmode
import android.app.ActivityManager.RunningTaskInfo
+import android.app.TaskInfo
+import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
import android.content.pm.ActivityInfo.isFixedOrientationLandscape
import android.content.pm.ActivityInfo.isFixedOrientationPortrait
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
@@ -105,7 +107,7 @@
* Calculates the largest size that can fit in a given area while maintaining a specific aspect
* ratio.
*/
-private fun maximumSizeMaintainingAspectRatio(
+fun maximumSizeMaintainingAspectRatio(
taskInfo: RunningTaskInfo,
targetArea: Size,
aspectRatio: Float
@@ -114,7 +116,8 @@
val targetWidth = targetArea.width
val finalHeight: Int
val finalWidth: Int
- if (isFixedOrientationPortrait(taskInfo.topActivityInfo!!.screenOrientation)) {
+ // Get orientation either through top activity or task's orientation
+ if (taskInfo.hasPortraitTopActivity()) {
val tempWidth = (targetHeight / aspectRatio).toInt()
if (tempWidth <= targetWidth) {
finalHeight = targetHeight
@@ -137,7 +140,7 @@
}
/** Calculates the aspect ratio of an activity from its fullscreen bounds. */
-private fun calculateAspectRatio(taskInfo: RunningTaskInfo): Float {
+fun calculateAspectRatio(taskInfo: RunningTaskInfo): Float {
if (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed) {
val appLetterboxWidth = taskInfo.appCompatTaskInfo.topActivityLetterboxWidth
val appLetterboxHeight = taskInfo.appCompatTaskInfo.topActivityLetterboxHeight
@@ -171,3 +174,41 @@
desiredSize.height + heightOffset
)
}
+
+/**
+ * Adjusts bounds to be positioned in the middle of the area provided, not necessarily the
+ * entire screen, as area can be offset by left and top start.
+ */
+fun centerInArea(desiredSize: Size, areaBounds: Rect, leftStart: Int, topStart: Int): Rect {
+ val heightOffset = (areaBounds.height() - desiredSize.height) / 2
+ val widthOffset = (areaBounds.width() - desiredSize.width) / 2
+
+ val newLeft = leftStart + widthOffset
+ val newTop = topStart + heightOffset
+ val newRight = newLeft + desiredSize.width
+ val newBottom = newTop + desiredSize.height
+
+ return Rect(newLeft, newTop, newRight, newBottom)
+}
+
+fun TaskInfo.hasPortraitTopActivity(): Boolean {
+ val topActivityScreenOrientation =
+ topActivityInfo?.screenOrientation ?: SCREEN_ORIENTATION_UNSPECIFIED
+ val appBounds = configuration.windowConfiguration.appBounds
+
+ return when {
+ // First check if activity has portrait screen orientation
+ topActivityScreenOrientation != SCREEN_ORIENTATION_UNSPECIFIED -> {
+ isFixedOrientationPortrait(topActivityScreenOrientation)
+ }
+
+ // Then check if the activity is portrait when letterboxed
+ appCompatTaskInfo.topActivityBoundsLetterboxed -> appCompatTaskInfo.isTopActivityPillarboxed
+
+ // Then check if the activity is portrait
+ appBounds != null -> appBounds.height() > appBounds.width()
+
+ // Otherwise just take the orientation of the task
+ else -> isFixedOrientationPortrait(configuration.orientation)
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 1965382..7cc01d5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -18,6 +18,7 @@
import android.app.ActivityManager.RunningTaskInfo
import android.app.ActivityOptions
+import android.app.KeyguardManager
import android.app.PendingIntent
import android.app.TaskInfo
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
@@ -35,6 +36,7 @@
import android.graphics.Region
import android.os.IBinder
import android.os.SystemProperties
+import android.util.Size
import android.view.Display.DEFAULT_DISPLAY
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CHANGE
@@ -108,6 +110,7 @@
private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
private val dragAndDropController: DragAndDropController,
private val transitions: Transitions,
+ private val keyguardManager: KeyguardManager,
private val enterDesktopTaskTransitionHandler: EnterDesktopTaskTransitionHandler,
private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
@@ -414,7 +417,7 @@
)
val wct = WindowContainerTransaction()
exitSplitIfApplicable(wct, taskInfo)
- moveHomeTaskToFront(wct)
+ moveHomeTask(wct, true /* toTop */)
val taskToMinimize =
bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
addMoveToDesktopChanges(wct, taskInfo)
@@ -647,13 +650,21 @@
fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) {
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
- val stableBounds = Rect()
- displayLayout.getStableBounds(stableBounds)
+ val stableBounds = Rect().apply { displayLayout.getStableBounds(this) }
+ val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
val destinationBounds = Rect()
- if (taskInfo.configuration.windowConfiguration.bounds == stableBounds) {
- // The desktop task is currently occupying the whole stable bounds. If the bounds
- // before the task was toggled to stable bounds were saved, toggle the task to those
- // bounds. Otherwise, toggle to the default bounds.
+
+ val isMaximized = if (taskInfo.isResizeable) {
+ currentTaskBounds == stableBounds
+ } else {
+ currentTaskBounds.width() == stableBounds.width()
+ || currentTaskBounds.height() == stableBounds.height()
+ }
+
+ if (isMaximized) {
+ // The desktop task is at the maximized width and/or height of the stable bounds.
+ // If the task's pre-maximize stable bounds were saved, toggle the task to those bounds.
+ // Otherwise, toggle to the default bounds.
val taskBoundsBeforeMaximize =
desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId)
if (taskBoundsBeforeMaximize != null) {
@@ -668,9 +679,20 @@
} else {
// Save current bounds so that task can be restored back to original bounds if necessary
// and toggle to the stable bounds.
- val taskBounds = taskInfo.configuration.windowConfiguration.bounds
- desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, taskBounds)
- destinationBounds.set(stableBounds)
+ desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, currentTaskBounds)
+
+ if (taskInfo.isResizeable) {
+ // if resizable then expand to entire stable bounds (full display minus insets)
+ destinationBounds.set(stableBounds)
+ } else {
+ // if non-resizable then calculate max bounds according to aspect ratio
+ val activityAspectRatio = calculateAspectRatio(taskInfo)
+ val newSize = maximumSizeMaintainingAspectRatio(taskInfo,
+ Size(stableBounds.width(), stableBounds.height()), activityAspectRatio)
+ val newBounds = centerInArea(
+ newSize, stableBounds, stableBounds.left, stableBounds.top)
+ destinationBounds.set(newBounds)
+ }
}
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
@@ -773,7 +795,7 @@
addWallpaperActivity(wct)
} else {
// Move home to front
- moveHomeTaskToFront(wct)
+ moveHomeTask(wct, true /* toTop */)
}
val nonMinimizedTasksOrderedFrontToBack =
@@ -799,11 +821,11 @@
return taskToMinimize
}
- private fun moveHomeTaskToFront(wct: WindowContainerTransaction) {
+ private fun moveHomeTask(wct: WindowContainerTransaction, toTop: Boolean) {
shellTaskOrganizer
.getRunningTasks(context.displayId)
.firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
- ?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
+ ?.let { homeTask -> wct.reorder(homeTask.getToken(), toTop /* onTop */) }
}
private fun addWallpaperActivity(wct: WindowContainerTransaction) {
@@ -972,6 +994,12 @@
transition: IBinder
): WindowContainerTransaction? {
KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFreeformTaskLaunch")
+ if (keyguardManager.isKeyguardLocked) {
+ // Do NOT handle freeform task launch when locked.
+ // It will be launched in fullscreen windowing mode (Details: b/160925539)
+ KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: skip keyguard is locked")
+ return null
+ }
if (!desktopModeTaskRepository.isDesktopModeShowing(task.displayId)) {
KtProtoLog.d(
WM_SHELL_DESKTOP_MODE,
@@ -1012,6 +1040,9 @@
)
return WindowContainerTransaction().also { wct ->
addMoveToDesktopChanges(wct, task)
+ // In some launches home task is moved behind new task being launched. Make sure
+ // that's not the case for launches in desktop.
+ moveHomeTask(wct, false /* toTop */)
// Desktop Mode is already showing and we're launching a new Task - we might need to
// minimize another Task.
val taskToMinimize = addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index 5335c0b..c35d77a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -28,7 +28,7 @@
import android.window.WindowContainerTransaction
import androidx.core.animation.addListener
import com.android.internal.jank.Cuj
-import com.android.wm.shell.common.InteractionJankMonitorUtils
+import com.android.internal.jank.InteractionJankMonitor
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
@@ -37,7 +37,8 @@
/** Handles the animation of quick resizing of desktop tasks. */
class ToggleResizeDesktopTaskTransitionHandler(
private val transitions: Transitions,
- private val transactionSupplier: Supplier<SurfaceControl.Transaction>
+ private val transactionSupplier: Supplier<SurfaceControl.Transaction>,
+ private val interactionJankMonitor: InteractionJankMonitor
) : Transitions.TransitionHandler {
private val rectEvaluator = RectEvaluator(Rect())
@@ -46,8 +47,9 @@
private var boundsAnimator: Animator? = null
constructor(
- transitions: Transitions
- ) : this(transitions, Supplier { SurfaceControl.Transaction() })
+ transitions: Transitions,
+ interactionJankMonitor: InteractionJankMonitor
+ ) : this(transitions, Supplier { SurfaceControl.Transaction() }, interactionJankMonitor)
/** Starts a quick resize transition. */
fun startTransition(wct: WindowContainerTransaction) {
@@ -105,7 +107,7 @@
onTaskResizeAnimationListener.onAnimationEnd(taskId)
finishCallback.onTransitionFinished(null)
boundsAnimator = null
- InteractionJankMonitorUtils.endTracing(
+ interactionJankMonitor.end(
Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW)
}
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index c374eb8..b3c3a3d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -59,9 +59,10 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
@@ -85,6 +86,7 @@
public class DragAndDropController implements RemoteCallable<DragAndDropController>,
GlobalDragListener.GlobalDragListenerCallback,
DisplayController.OnDisplaysChangedListener,
+ ShellTaskOrganizer.TaskVanishedListener,
View.OnDragListener, ComponentCallbacks2 {
private static final String TAG = DragAndDropController.class.getSimpleName();
@@ -92,6 +94,7 @@
private final Context mContext;
private final ShellController mShellController;
private final ShellCommandHandler mShellCommandHandler;
+ private final ShellTaskOrganizer mShellTaskOrganizer;
private final DisplayController mDisplayController;
private final DragAndDropEventLogger mLogger;
private final IconProvider mIconProvider;
@@ -133,6 +136,7 @@
ShellInit shellInit,
ShellController shellController,
ShellCommandHandler shellCommandHandler,
+ ShellTaskOrganizer shellTaskOrganizer,
DisplayController displayController,
UiEventLogger uiEventLogger,
IconProvider iconProvider,
@@ -142,6 +146,7 @@
mContext = context;
mShellController = shellController;
mShellCommandHandler = shellCommandHandler;
+ mShellTaskOrganizer = shellTaskOrganizer;
mDisplayController = displayController;
mLogger = new DragAndDropEventLogger(uiEventLogger);
mIconProvider = iconProvider;
@@ -163,6 +168,7 @@
}, 0);
mShellController.addExternalInterface(KEY_EXTRA_SHELL_DRAG_AND_DROP,
this::createExternalInterface, this);
+ mShellTaskOrganizer.addTaskVanishedListener(this);
mShellCommandHandler.addDumpCallback(this::dump, this);
mGlobalDragListener.setListener(this);
}
@@ -281,6 +287,34 @@
}
@Override
+ public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ if (taskInfo.baseIntent == null) {
+ // Invalid info
+ return;
+ }
+ // Find the active drag
+ PerDisplay pd = null;
+ for (int i = 0; i < mDisplayDropTargets.size(); i++) {
+ final PerDisplay iPd = mDisplayDropTargets.valueAt(i);
+ if (iPd.isHandlingDrag) {
+ pd = iPd;
+ break;
+ }
+ }
+ if (pd == null || !pd.isHandlingDrag) {
+ // Not currently dragging
+ return;
+ }
+
+ // Update the drag session
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Handling vanished task: id=%d component=%s", taskInfo.taskId,
+ taskInfo.baseIntent.getComponent());
+ pd.dragSession.updateRunningTask();
+ pd.dragLayout.updateSession(pd.dragSession);
+ }
+
+ @Override
public boolean onDrag(View target, DragEvent event) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
"Drag event: action=%s x=%f y=%f xOffset=%f yOffset=%f",
@@ -313,11 +347,10 @@
Slog.w(TAG, "Unexpected drag start during an active drag");
return false;
}
- // TODO(b/290391688): Also update the session data with task stack changes
pd.dragSession = new DragSession(ActivityTaskManager.getInstance(),
mDisplayController.getDisplayLayout(displayId), event.getClipData(),
event.getDragFlags());
- pd.dragSession.update();
+ pd.dragSession.initialize();
pd.activeDragCount++;
pd.dragLayout.prepare(pd.dragSession, mLogger.logStart(pd.dragSession));
setDropTargetWindowVisibility(pd, View.VISIBLE);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index a42ca19..9c7476d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -66,7 +66,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -84,7 +84,10 @@
private static final String TAG = DragAndDropPolicy.class.getSimpleName();
private final Context mContext;
- private final Starter mStarter;
+ // Used only for launching a fullscreen task (or as a fallback if there is no split starter)
+ private final Starter mFullscreenStarter;
+ // Used for launching tasks into splitscreen
+ private final Starter mSplitscreenStarter;
private final SplitScreenController mSplitScreen;
private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>();
private final RectF mDisallowHitRegion = new RectF();
@@ -97,10 +100,12 @@
}
@VisibleForTesting
- DragAndDropPolicy(Context context, SplitScreenController splitScreen, Starter starter) {
+ DragAndDropPolicy(Context context, SplitScreenController splitScreen,
+ Starter fullscreenStarter) {
mContext = context;
mSplitScreen = splitScreen;
- mStarter = mSplitScreen != null ? mSplitScreen : starter;
+ mFullscreenStarter = fullscreenStarter;
+ mSplitscreenStarter = splitScreen;
}
/**
@@ -245,17 +250,20 @@
mSplitScreen.onDroppedToSplit(position, mLoggerSessionId);
}
+ final Starter starter = target.type == TYPE_FULLSCREEN
+ ? mFullscreenStarter
+ : mSplitscreenStarter;
if (mSession.appData != null) {
- launchApp(mSession, position);
+ launchApp(mSession, starter, position);
} else {
- launchIntent(mSession, position);
+ launchIntent(mSession, starter, position);
}
}
/**
* Launches an app provided by SysUI.
*/
- private void launchApp(DragSession session, @SplitPosition int position) {
+ private void launchApp(DragSession session, Starter starter, @SplitPosition int position) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching app data at position=%d",
position);
final ClipDescription description = session.getClipDescription();
@@ -275,11 +283,11 @@
if (isTask) {
final int taskId = session.appData.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID);
- mStarter.startTask(taskId, position, opts);
+ starter.startTask(taskId, position, opts);
} else if (isShortcut) {
final String packageName = session.appData.getStringExtra(EXTRA_PACKAGE_NAME);
final String id = session.appData.getStringExtra(EXTRA_SHORTCUT_ID);
- mStarter.startShortcut(packageName, id, position, opts, user);
+ starter.startShortcut(packageName, id, position, opts, user);
} else {
final PendingIntent launchIntent =
session.appData.getParcelableExtra(EXTRA_PENDING_INTENT);
@@ -288,7 +296,7 @@
Log.e(TAG, "Expected app intent's EXTRA_USER to match pending intent user");
}
}
- mStarter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
+ starter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
position, opts);
}
}
@@ -296,7 +304,7 @@
/**
* Launches an intent sender provided by an application.
*/
- private void launchIntent(DragSession session, @SplitPosition int position) {
+ private void launchIntent(DragSession session, Starter starter, @SplitPosition int position) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching intent at position=%d",
position);
final ActivityOptions baseActivityOpts = ActivityOptions.makeBasic();
@@ -309,7 +317,7 @@
| FLAG_ACTIVITY_MULTIPLE_TASK);
final Bundle opts = baseActivityOpts.toBundle();
- mStarter.startIntent(session.launchableIntent,
+ starter.startIntent(session.launchableIntent,
session.launchableIntent.getCreatorUserHandle().getIdentifier(),
null /* fillIntent */, position, opts);
}
@@ -420,7 +428,7 @@
@Override
public String toString() {
- return "Target {hit=" + hitRegion + " draw=" + drawRegion + "}";
+ return "Target {type=" + type + " hit=" + hitRegion + " draw=" + drawRegion + "}";
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index 4bb10df..910175e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -20,7 +20,6 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -42,6 +41,7 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Insets;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
@@ -55,7 +55,7 @@
import androidx.annotation.NonNull;
import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
@@ -102,6 +102,8 @@
private boolean mIsShowing;
private boolean mHasDropped;
private DragSession mSession;
+ // The last position that was handled by the drag layout
+ private final Point mLastPosition = new Point();
@SuppressLint("WrongConstant")
public DragLayout(Context context, SplitScreenController splitScreenController,
@@ -265,6 +267,15 @@
*/
public void prepare(DragSession session, InstanceId loggerSessionId) {
mPolicy.start(session, loggerSessionId);
+ updateSession(session);
+ }
+
+ /**
+ * Updates the drag layout based on the diven drag session.
+ */
+ public void updateSession(DragSession session) {
+ // Note: The policy currently just keeps a reference to the session
+ boolean updatingExistingSession = mSession != null;
mSession = session;
mHasDropped = false;
mCurrentTarget = null;
@@ -312,6 +323,11 @@
updateDropZoneSizes(topOrLeftBounds, bottomOrRightBounds);
}
requestLayout();
+ if (updatingExistingSession) {
+ // Update targets if we are already currently dragging
+ recomputeDropTargets();
+ update(mLastPosition.x, mLastPosition.y);
+ }
}
private void updateDropZoneSizesForSingleTask() {
@@ -359,6 +375,9 @@
mDropZoneView2.setLayoutParams(dropZoneView2);
}
+ /**
+ * Shows the drag layout.
+ */
public void show() {
mIsShowing = true;
recomputeDropTargets();
@@ -384,13 +403,19 @@
* Updates the visible drop target as the user drags.
*/
public void update(DragEvent event) {
+ update((int) event.getX(), (int) event.getY());
+ }
+
+ /**
+ * Updates the visible drop target as the user drags to the given coordinates.
+ */
+ private void update(int x, int y) {
if (mHasDropped) {
return;
}
// Find containing region, if the same as mCurrentRegion, then skip, otherwise, animate the
// visibility of the current region
- DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(
- (int) event.getX(), (int) event.getY());
+ DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(x, y);
if (mCurrentTarget != target) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current target: %s", target);
if (target == null) {
@@ -429,6 +454,7 @@
}
mCurrentTarget = target;
}
+ mLastPosition.set(x, y);
}
/**
@@ -436,6 +462,7 @@
*/
public void hide(DragEvent event, Runnable hideCompleteCallback) {
mIsShowing = false;
+ mLastPosition.set(-1, -1);
animateSplitContainers(false, () -> {
if (hideCompleteCallback != null) {
hideCompleteCallback.run();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
index 0addd43..3bedef2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
@@ -30,7 +30,9 @@
import androidx.annotation.Nullable;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.List;
@@ -79,17 +81,27 @@
}
/**
- * Updates the session data based on the current state of the system.
+ * Updates the running task for this drag session.
*/
- void update() {
- List<ActivityManager.RunningTaskInfo> tasks =
+ void updateRunningTask() {
+ final List<ActivityManager.RunningTaskInfo> tasks =
mActivityTaskManager.getTasks(1, false /* filterOnlyVisibleRecents */);
if (!tasks.isEmpty()) {
final ActivityManager.RunningTaskInfo task = tasks.get(0);
runningTaskInfo = task;
runningTaskWinMode = task.getWindowingMode();
runningTaskActType = task.getActivityType();
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Running task: id=%d component=%s", task.taskId,
+ task.baseIntent != null ? task.baseIntent.getComponent() : "null");
}
+ }
+
+ /**
+ * Updates the session data based on the current state of the system at the start of the drag.
+ */
+ void initialize() {
+ updateRunningTask();
activityInfo = mInitialDragData.getItemAt(0).getActivityInfo();
// TODO: This should technically check & respect config_supportsNonResizableMultiWindow
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
index 724a130..b6b49a8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
@@ -19,6 +19,7 @@
import static com.android.wm.shell.animation.Interpolators.FAST_OUT_SLOW_IN;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
@@ -37,13 +38,16 @@
import androidx.annotation.Nullable;
import com.android.internal.policy.ScreenDecorationsUtils;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
/**
* Renders a drop zone area for items being dragged.
*/
public class DropZoneView extends FrameLayout {
+ private static final boolean DEBUG_LAYOUT = false;
private static final float SPLASHSCREEN_ALPHA = 0.90f;
private static final float HIGHLIGHT_ALPHA = 1f;
private static final int MARGIN_ANIMATION_ENTER_DURATION = 400;
@@ -77,6 +81,7 @@
private int mHighlightColor;
private ObjectAnimator mBackgroundAnimator;
+ private int mTargetBackgroundColor;
private ObjectAnimator mMarginAnimator;
private float mMarginPercent;
@@ -181,6 +186,9 @@
/** Animates between highlight and splashscreen depending on current state. */
public void animateSwitch() {
+ if (DEBUG_LAYOUT) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "animateSwitch");
+ }
mShowingHighlight = !mShowingHighlight;
mShowingSplash = !mShowingHighlight;
final int newColor = mShowingHighlight ? mHighlightColor : mSplashScreenColor;
@@ -190,6 +198,10 @@
/** Animates the highlight indicating the zone is hovered on or not. */
public void setShowingHighlight(boolean showingHighlight) {
+ if (DEBUG_LAYOUT) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "setShowingHighlight: showing=%b",
+ showingHighlight);
+ }
mShowingHighlight = showingHighlight;
mShowingSplash = !mShowingHighlight;
final int newColor = mShowingHighlight ? mHighlightColor : mSplashScreenColor;
@@ -199,6 +211,10 @@
/** Animates the margins around the drop zone to show or hide. */
public void setShowingMargin(boolean visible) {
+ if (DEBUG_LAYOUT) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "setShowingMargin: visible=%b",
+ visible);
+ }
if (mShowingMargin != visible) {
mShowingMargin = visible;
animateMarginToState();
@@ -212,6 +228,15 @@
}
private void animateBackground(int startColor, int endColor) {
+ if (DEBUG_LAYOUT) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "animateBackground: start=%s end=%s",
+ Integer.toHexString(startColor), Integer.toHexString(endColor));
+ }
+ if (endColor == mTargetBackgroundColor) {
+ // Already at, or animating to, that background color
+ return;
+ }
if (mBackgroundAnimator != null) {
mBackgroundAnimator.cancel();
}
@@ -223,6 +248,7 @@
mBackgroundAnimator.setInterpolator(FAST_OUT_SLOW_IN);
}
mBackgroundAnimator.start();
+ mTargetBackgroundColor = endColor;
}
private void animateSplashScreenIcon() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
index 31214eb..ffcfe644 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
@@ -25,7 +25,7 @@
import android.window.IGlobalDragListener
import android.window.IUnhandledDragCallback
import androidx.annotation.VisibleForTesting
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.protolog.ShellProtoLogGroup
import java.util.function.Consumer
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index b48aee5..1641668 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -25,7 +25,7 @@
import android.util.SparseArray;
import android.view.SurfaceControl;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 2626e73..d2ceb67 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -27,7 +27,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index cd478e5..333c75f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -49,7 +49,7 @@
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
index ce98458..93ede7a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
@@ -16,7 +16,6 @@
package com.android.wm.shell.pip;
-import android.content.ComponentName;
import android.os.RemoteException;
import android.view.IPinnedTaskListener;
import android.view.WindowManagerGlobal;
@@ -70,12 +69,6 @@
}
}
- private void onActivityHidden(ComponentName componentName) {
- for (PinnedTaskListener listener : mListeners) {
- listener.onActivityHidden(componentName);
- }
- }
-
@BinderThread
private class PinnedTaskListenerImpl extends IPinnedTaskListener.Stub {
@Override
@@ -91,13 +84,6 @@
PinnedStackListenerForwarder.this.onImeVisibilityChanged(imeVisible, imeHeight);
});
}
-
- @Override
- public void onActivityHidden(ComponentName componentName) {
- mMainExecutor.execute(() -> {
- PinnedStackListenerForwarder.this.onActivityHidden(componentName);
- });
- }
}
/**
@@ -108,7 +94,5 @@
public void onMovementBoundsChanged(boolean fromImeAdjustment) {}
public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {}
-
- public void onActivityHidden(ComponentName componentName) {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
index a749019..b27c428 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
@@ -16,10 +16,12 @@
package com.android.wm.shell.pip;
+import android.annotation.NonNull;
import android.graphics.Rect;
import com.android.wm.shell.shared.annotations.ExternalThread;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
@@ -69,9 +71,10 @@
default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
/**
- * @return {@link PipTransitionController} instance.
+ * Register {@link PipTransitionController.PipTransitionCallback} to listen on PiP transition
+ * started / finished callbacks.
*/
- default PipTransitionController getPipTransitionController() {
- return null;
- }
+ default void registerPipTransitionCallback(
+ @NonNull PipTransitionController.PipTransitionCallback callback,
+ @NonNull Executor executor) { }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 0a3c15b..a8346a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.pip;
import static android.util.RotationUtils.rotateBounds;
+import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -37,7 +38,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.pip.PipUtils;
@@ -625,6 +626,14 @@
}
} else {
adjustedSourceRectHint.set(sourceRectHint);
+ if (isInPipDirection(direction)
+ && rotationDelta == ROTATION_0
+ && taskInfo.displayCutoutInsets != null) {
+ // TODO: this is to special case the issues on Foldable device
+ // with display cutout. This aligns with what's in SwipePipToHomeAnimator.
+ adjustedSourceRectHint.offset(taskInfo.displayCutoutInsets.left,
+ taskInfo.displayCutoutInsets.top);
+ }
}
final Rect sourceHintRectInsets = new Rect();
if (!adjustedSourceRectHint.isEmpty()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index e2e1ecd..6a6e2ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -73,7 +73,7 @@
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.animation.Interpolators;
@@ -423,7 +423,8 @@
});
mPipTransitionController.setPipOrganizer(this);
displayController.addDisplayWindowListener(this);
- pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback);
+ pipTransitionController.registerPipTransitionCallback(
+ mPipTransitionCallback, mMainExecutor);
}
}
@@ -635,6 +636,13 @@
return;
}
+ // bail early if leash is null
+ if (mLeash == null) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "exitPip: leash is null");
+ return;
+ }
+
final Rect destinationBounds = new Rect(getExitDestinationBounds());
final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit)
? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 3cae72d..e5633de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -24,6 +24,7 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -62,7 +63,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
@@ -300,6 +301,10 @@
finishTransaction);
}
+ if (isCurrentPipActivityClosed(info)) {
+ mPipBoundsState.setLastPipComponentName(null /* componentName */);
+ }
+
return false;
}
@@ -322,6 +327,21 @@
return true;
}
+ private boolean isCurrentPipActivityClosed(TransitionInfo info) {
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ TransitionInfo.Change change = info.getChanges().get(i);
+ boolean isTaskChange = change.getTaskInfo() != null;
+ boolean hasComponentNameOfPip = change.getActivityComponent() != null
+ && change.getActivityComponent().equals(
+ mPipBoundsState.getLastPipComponentName());
+ if (!isTaskChange && change.getMode() == TRANSIT_CLOSE && hasComponentNameOfPip) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 6eefdcf..8d36db9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -41,7 +41,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
@@ -53,8 +53,9 @@
import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
/**
* Responsible supplying PiP Transitions.
@@ -66,7 +67,7 @@
protected final ShellTaskOrganizer mShellTaskOrganizer;
protected final PipMenuController mPipMenuController;
protected final Transitions mTransitions;
- private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
+ private final Map<PipTransitionCallback, Executor> mPipTransitionCallbacks = new HashMap<>();
protected PipTaskOrganizer mPipOrganizer;
protected DefaultMixedHandler mMixedHandler;
@@ -126,8 +127,10 @@
/**
* Called when the Shell wants to start resizing Pip transition/animation.
+ *
+ * @param duration the suggested duration for resize animation.
*/
- public void startResizeTransition(WindowContainerTransaction wct) {
+ public void startResizeTransition(WindowContainerTransaction wct, int duration) {
// Default implementation does nothing.
}
@@ -181,16 +184,18 @@
/**
* Registers {@link PipTransitionCallback} to receive transition callbacks.
*/
- public void registerPipTransitionCallback(PipTransitionCallback callback) {
- mPipTransitionCallbacks.add(callback);
+ public void registerPipTransitionCallback(
+ @NonNull PipTransitionCallback callback, @NonNull Executor executor) {
+ mPipTransitionCallbacks.put(callback, executor);
}
protected void sendOnPipTransitionStarted(
@PipAnimationController.TransitionDirection int direction) {
final Rect pipBounds = mPipBoundsState.getBounds();
- for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
- final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
- callback.onPipTransitionStarted(direction, pipBounds);
+ for (Map.Entry<PipTransitionCallback, Executor> entry
+ : mPipTransitionCallbacks.entrySet()) {
+ entry.getValue().execute(
+ () -> entry.getKey().onPipTransitionStarted(direction, pipBounds));
}
if (isInPipDirection(direction) && Flags.enablePipUiStateCallbackOnEntering()) {
try {
@@ -207,9 +212,10 @@
protected void sendOnPipTransitionFinished(
@PipAnimationController.TransitionDirection int direction) {
- for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
- final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
- callback.onPipTransitionFinished(direction);
+ for (Map.Entry<PipTransitionCallback, Executor> entry
+ : mPipTransitionCallbacks.entrySet()) {
+ entry.getValue().execute(
+ () -> entry.getKey().onPipTransitionFinished(direction));
}
if (isInPipDirection(direction) && Flags.enablePipUiStateCallbackOnEntering()) {
try {
@@ -226,9 +232,10 @@
protected void sendOnPipTransitionCancelled(
@PipAnimationController.TransitionDirection int direction) {
- for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
- final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
- callback.onPipTransitionCanceled(direction);
+ for (Map.Entry<PipTransitionCallback, Executor> entry
+ : mPipTransitionCallbacks.entrySet()) {
+ entry.getValue().execute(
+ () -> entry.getKey().onPipTransitionCanceled(direction));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 0169e8c..c7369a3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -32,7 +32,7 @@
import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.pip.PipBoundsState;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 8c4bf76..d1d8275 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -59,7 +59,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayChangeController;
@@ -106,6 +106,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
@@ -367,15 +368,6 @@
false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */,
null /* windowContainerTransaction */);
}
-
- @Override
- public void onActivityHidden(ComponentName componentName) {
- if (componentName.equals(mPipBoundsState.getLastPipComponentName())) {
- // The activity was removed, we don't want to restore to the reentry state
- // saved for this component anymore.
- mPipBoundsState.setLastPipComponentName(null);
- }
- }
}
/**
@@ -487,7 +479,7 @@
mShellCommandHandler.addDumpCallback(this::dump, this);
mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(),
INPUT_CONSUMER_PIP, mMainExecutor);
- mPipTransitionController.registerPipTransitionCallback(this);
+ mPipTransitionController.registerPipTransitionCallback(this, mMainExecutor);
mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> {
mPipDisplayLayoutState.setDisplayId(displayId);
onDisplayChanged(mDisplayController.getDisplayLayout(displayId),
@@ -1229,8 +1221,11 @@
}
@Override
- public PipTransitionController getPipTransitionController() {
- return mPipTransitionController;
+ public void registerPipTransitionCallback(
+ PipTransitionController.PipTransitionCallback callback,
+ Executor executor) {
+ mMainExecutor.execute(() -> mPipTransitionController.registerPipTransitionCallback(
+ callback, executor));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
index f6cab48..d1978c3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
@@ -28,7 +28,7 @@
import android.view.InputChannel;
import android.view.InputEvent;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 15342be..c189642 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -59,7 +59,7 @@
import android.widget.FrameLayout;
import android.widget.LinearLayout;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index ef46843..df3803d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -34,10 +34,11 @@
import android.graphics.Rect;
import android.os.Debug;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.FloatProperties;
import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
import com.android.wm.shell.common.pip.PipAppOpsListener;
import com.android.wm.shell.common.pip.PipBoundsState;
@@ -47,6 +48,7 @@
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.animation.PhysicsAnimator;
+import com.android.wm.shell.shared.annotations.ShellMainThread;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
@@ -171,7 +173,9 @@
public void onPipTransitionCanceled(int direction) {}
};
- public PipMotionHelper(Context context, @NonNull PipBoundsState pipBoundsState,
+ public PipMotionHelper(Context context,
+ @ShellMainThread ShellExecutor mainExecutor,
+ @NonNull PipBoundsState pipBoundsState,
PipTaskOrganizer pipTaskOrganizer, PhonePipMenuController menuController,
PipSnapAlgorithm snapAlgorithm, PipTransitionController pipTransitionController,
FloatingContentCoordinator floatingContentCoordinator,
@@ -183,7 +187,7 @@
mSnapAlgorithm = snapAlgorithm;
mFloatingContentCoordinator = floatingContentCoordinator;
mPipPerfHintController = pipPerfHintControllerOptional.orElse(null);
- pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback);
+ pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback, mainExecutor);
mResizePipUpdateListener = (target, values) -> {
if (mPipBoundsState.getMotionBoundsState().isInMotion()) {
mPipTaskOrganizer.scheduleUserResizePip(getBounds(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index d8ac8e9..9c4e723 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -48,7 +48,7 @@
import android.view.accessibility.AccessibilityWindowInfo;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
index 5d858fa..cb82db6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
@@ -23,7 +23,7 @@
import android.view.ViewConfiguration;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
index 6b890c4..50d22ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
@@ -33,7 +33,7 @@
import android.content.Context;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.common.pip.PipUtils;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java
index 0221db8..eb7a10c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java
@@ -28,7 +28,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index 72c0cd7..188c35f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -33,7 +33,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java
index 8a215b4..1afb470 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java
@@ -26,7 +26,7 @@
import android.os.Handler;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 3d28646..0ed5079 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -39,7 +39,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
@@ -257,7 +257,7 @@
}
private void onInit() {
- mPipTransitionController.registerPipTransitionCallback(this);
+ mPipTransitionController.registerPipTransitionCallback(this, mMainExecutor);
reloadResources();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
index 977aad4..327ceef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
@@ -27,7 +27,7 @@
import android.os.Bundle;
import android.os.Handler;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.TvWindowMenuActionButton;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index 6b5bdd2..e74870d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -37,7 +37,7 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.pip.PipMenuController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
index adc03cf..eabf1b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
@@ -39,7 +39,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import java.util.Arrays;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 4a767ef..c7704f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -50,7 +50,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.widget.LinearLayoutManager;
import com.android.internal.widget.RecyclerView;
import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index 54e162b..ce50792 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -33,7 +33,7 @@
import android.text.TextUtils;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ImageUtils;
import com.android.wm.shell.R;
import com.android.wm.shell.common.pip.PipMediaController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
index ca0d61f..7a0e669 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
@@ -62,7 +62,7 @@
import androidx.annotation.Nullable;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
index 5c561fe..88f9e4c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
@@ -47,9 +47,17 @@
@Nullable
private Runnable mAnimationEndCallback;
private RectEvaluator mRectEvaluator;
+
+ // Bounds relative to which scaling/cropping must be done.
private final Rect mBaseBounds = new Rect();
+
+ // Bounds to animate from.
private final Rect mStartBounds = new Rect();
+
+ // Target bounds.
private final Rect mEndBounds = new Rect();
+
+ // Bounds updated by the evaluator as animator is running.
private final Rect mAnimatedRect = new Rect();
private final float mDelta;
@@ -84,7 +92,6 @@
addListener(this);
addUpdateListener(this);
setEvaluator(mRectEvaluator);
- // TODO: change this
setDuration(duration);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
index 6e36a32..9cfe162 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
@@ -32,7 +32,7 @@
import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.pip.PipBoundsState;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index fc0d36d..06adad6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -36,7 +36,7 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.Preconditions;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -352,6 +352,7 @@
mPipBoundsAlgorithm.dump(pw, innerPrefix);
mPipBoundsState.dump(pw, innerPrefix);
mPipDisplayLayoutState.dump(pw, innerPrefix);
+ mPipTransitionState.dump(pw, innerPrefix);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
index b757b00..ffda56d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
@@ -28,7 +28,7 @@
import android.view.InputChannel;
import android.view.InputEvent;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java
index 42b8e9f..c54e4cd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java
@@ -59,7 +59,7 @@
import android.widget.FrameLayout;
import android.widget.LinearLayout;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index 495cd00..e277a8d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip2.phone;
+import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY;
import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_NO_BOUNCY;
import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW;
import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_MEDIUM;
@@ -25,6 +26,7 @@
import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_RIGHT;
import static com.android.wm.shell.pip2.phone.PipMenuView.ANIM_TYPE_DISMISS;
import static com.android.wm.shell.pip2.phone.PipMenuView.ANIM_TYPE_NONE;
+import static com.android.wm.shell.pip2.phone.PipTransition.ANIMATING_BOUNDS_CHANGE_DURATION;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -35,7 +37,8 @@
import android.os.Debug;
import android.view.SurfaceControl;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
+import com.android.internal.util.Preconditions;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.FloatProperties;
import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -45,6 +48,7 @@
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipPerfHintController;
import com.android.wm.shell.common.pip.PipSnapAlgorithm;
+import com.android.wm.shell.pip2.animation.PipResizeAnimator;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.animation.PhysicsAnimator;
@@ -62,6 +66,7 @@
PipTransitionState.PipTransitionStateChangedListener {
private static final String TAG = "PipMotionHelper";
private static final String FLING_BOUNDS_CHANGE = "fling_bounds_change";
+ private static final String ANIMATING_BOUNDS_CHANGE = "animating_bounds_change";
private static final boolean DEBUG = false;
private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
@@ -113,7 +118,7 @@
/** SpringConfig to use for fling-then-spring animations. */
private final PhysicsAnimator.SpringConfig mSpringConfig =
- new PhysicsAnimator.SpringConfig(700f, DAMPING_RATIO_NO_BOUNCY);
+ new PhysicsAnimator.SpringConfig(300f, DAMPING_RATIO_LOW_BOUNCY);
/** SpringConfig used for animating into the dismiss region, matches the one in
* {@link MagnetizedObject}. */
@@ -152,9 +157,16 @@
private boolean mDismissalPending = false;
/**
- * Set to true if bounds change transition has been scheduled from PipMotionHelper.
+ * Set to true if bounds change transition has been scheduled from PipMotionHelper
+ * after animating is over.
*/
- private boolean mWaitingForBoundsChangeTransition = false;
+ private boolean mWaitingForFlingTransition = false;
+
+ /**
+ * Set to true if bounds change transition has been scheduled from PipMotionHelper,
+ * and if the animation is supposed to run while transition is playing.
+ */
+ private boolean mWaitingToPlayBoundsChangeTransition = false;
/**
* Gets set in {@link #animateToExpandedState(Rect, Rect, Rect, Runnable)}, this callback is
@@ -634,6 +646,9 @@
// The physics animation ended, though we may not necessarily be done animating, such as
// when we're still dragging after moving out of the magnetic target.
if (!mDismissalPending && !mSpringingToTouch && !mMagnetizedPip.getObjectStuckToTarget()) {
+ // Update the earlier estimate on bounds we are animating towards, since physics
+ // animator is non-deterministic.
+ setAnimatingToBounds(mPipBoundsState.getMotionBoundsState().getBoundsInMotion());
// do not schedule resize if PiP is dismissing, which may cause app re-open to
// mBounds instead of its normal bounds.
Bundle extra = new Bundle();
@@ -673,6 +688,11 @@
* Directly resizes the PiP to the given {@param bounds}.
*/
private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
+ if (mPipBoundsState.getMotionBoundsState().isInMotion()) {
+ // Do not carry out any resizing if we are dragging or physics animator is running.
+ return;
+ }
+
if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: resizeAndAnimatePipUnchecked: toBounds=%s"
@@ -682,10 +702,11 @@
// Intentionally resize here even if the current bounds match the destination bounds.
// This is so all the proper callbacks are performed.
-
- // mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration,
- // TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND, null /* updateBoundsCallback */);
- // setAnimatingToBounds(toBounds);
+ setAnimatingToBounds(toBounds);
+ Bundle extra = new Bundle();
+ extra.putBoolean(ANIMATING_BOUNDS_CHANGE, true);
+ extra.putInt(ANIMATING_BOUNDS_CHANGE_DURATION, duration);
+ mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra);
}
@Override
@@ -694,7 +715,11 @@
@Nullable Bundle extra) {
switch (newState) {
case PipTransitionState.SCHEDULED_BOUNDS_CHANGE:
- if (!extra.getBoolean(FLING_BOUNDS_CHANGE)) break;
+ mWaitingForFlingTransition = extra.getBoolean(FLING_BOUNDS_CHANGE);
+ mWaitingToPlayBoundsChangeTransition = extra.getBoolean(ANIMATING_BOUNDS_CHANGE);
+ if (!mWaitingForFlingTransition && !mWaitingToPlayBoundsChangeTransition) {
+ break;
+ }
if (mPipBoundsState.getBounds().equals(
mPipBoundsState.getMotionBoundsState().getBoundsInMotion())) {
@@ -709,30 +734,30 @@
break;
}
- // If touch is turned off and we are in a fling animation, schedule a transition.
- mWaitingForBoundsChangeTransition = true;
+ // Delay config until the end, if we are animating after scheduling the transition.
mPipScheduler.scheduleAnimateResizePip(
- mPipBoundsState.getMotionBoundsState().getBoundsInMotion());
+ mPipBoundsState.getMotionBoundsState().getAnimatingToBounds(),
+ mWaitingToPlayBoundsChangeTransition,
+ extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION,
+ PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION));
break;
case PipTransitionState.CHANGING_PIP_BOUNDS:
- if (!mWaitingForBoundsChangeTransition) break;
-
- // If bounds change transition was scheduled from this class, handle leash updates.
- mWaitingForBoundsChangeTransition = false;
SurfaceControl.Transaction startTx = extra.getParcelable(
PipTransition.PIP_START_TX, SurfaceControl.Transaction.class);
+ SurfaceControl.Transaction finishTx = extra.getParcelable(
+ PipTransition.PIP_FINISH_TX, SurfaceControl.Transaction.class);
Rect destinationBounds = extra.getParcelable(
PipTransition.PIP_DESTINATION_BOUNDS, Rect.class);
- startTx.setPosition(mPipTransitionState.mPinnedTaskLeash,
- destinationBounds.left, destinationBounds.top);
- startTx.apply();
+ final int duration = extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION,
+ PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION);
- // All motion operations have actually finished, so make bounds cache updates.
- settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);
- cleanUpHighPerfSessionMaybe();
-
- // Signal that the transition is done - should update transition state by default.
- mPipScheduler.scheduleFinishResizePip(false /* configAtEnd */);
+ if (mWaitingForFlingTransition) {
+ mWaitingForFlingTransition = false;
+ handleFlingTransition(startTx, finishTx, destinationBounds);
+ } else if (mWaitingToPlayBoundsChangeTransition) {
+ mWaitingToPlayBoundsChangeTransition = false;
+ startResizeAnimation(startTx, finishTx, destinationBounds, duration);
+ }
break;
case PipTransitionState.EXITING_PIP:
// We need to force finish any local animators if about to leave PiP, to avoid
@@ -740,9 +765,46 @@
if (!mPipBoundsState.getMotionBoundsState().isInMotion()) break;
cancelPhysicsAnimation();
settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);
+ break;
}
}
+ private void handleFlingTransition(SurfaceControl.Transaction startTx,
+ SurfaceControl.Transaction finishTx, Rect destinationBounds) {
+ startTx.setPosition(mPipTransitionState.mPinnedTaskLeash,
+ destinationBounds.left, destinationBounds.top);
+ startTx.apply();
+
+ // All motion operations have actually finished, so make bounds cache updates.
+ settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);
+ cleanUpHighPerfSessionMaybe();
+
+ // Signal that the transition is done - should update transition state by default.
+ mPipScheduler.scheduleFinishResizePip(false /* configAtEnd */);
+ }
+
+ private void startResizeAnimation(SurfaceControl.Transaction startTx,
+ SurfaceControl.Transaction finishTx, Rect destinationBounds, int duration) {
+ SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+ Preconditions.checkState(pipLeash != null,
+ "No leash cached by mPipTransitionState=" + mPipTransitionState);
+
+ startTx.setWindowCrop(pipLeash, mPipBoundsState.getBounds().width(),
+ mPipBoundsState.getBounds().height());
+
+ PipResizeAnimator animator = new PipResizeAnimator(mContext, pipLeash,
+ startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(),
+ destinationBounds, duration, 0f /* angle */);
+ animator.setAnimationEndCallback(() -> {
+ mPipBoundsState.setBounds(destinationBounds);
+ // All motion operations have actually finished, so make bounds cache updates.
+ cleanUpHighPerfSessionMaybe();
+ // Signal that we are done with resize transition
+ mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */);
+ });
+ animator.start();
+ }
+
private void settlePipBoundsAfterPhysicsAnimation(boolean animatingAfter) {
if (!animatingAfter) {
// The physics animation ended, though we may not necessarily be done animating, such as
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
index 33e80bd..5b0ca18 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip2.phone;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
+import static com.android.wm.shell.pip2.phone.PipTransition.ANIMATING_BOUNDS_CHANGE_DURATION;
import android.annotation.Nullable;
import android.content.Context;
@@ -535,7 +536,8 @@
mWaitingForBoundsChangeTransition = true;
// Schedule PiP resize transition, but delay any config updates until very end.
- mPipScheduler.scheduleAnimateResizePip(mLastResizeBounds, true /* configAtEnd */);
+ mPipScheduler.scheduleAnimateResizePip(mLastResizeBounds,
+ true /* configAtEnd */, PINCH_RESIZE_SNAP_DURATION);
break;
case PipTransitionState.CHANGING_PIP_BOUNDS:
if (!mWaitingForBoundsChangeTransition) break;
@@ -550,12 +552,15 @@
PipTransition.PIP_START_TX, SurfaceControl.Transaction.class);
SurfaceControl.Transaction finishTx = extra.getParcelable(
PipTransition.PIP_FINISH_TX, SurfaceControl.Transaction.class);
+ final int duration = extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION,
+ PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION);
+
startTx.setWindowCrop(pipLeash, mPipBoundsState.getBounds().width(),
mPipBoundsState.getBounds().height());
PipResizeAnimator animator = new PipResizeAnimator(mContext, pipLeash,
startTx, finishTx, mPipBoundsState.getBounds(), mStartBoundsAfterRelease,
- mLastResizeBounds, PINCH_RESIZE_SNAP_DURATION, mAngle);
+ mLastResizeBounds, duration, mAngle);
animator.setAnimationEndCallback(() -> {
// All motion operations have actually finished, so make bounds cache updates.
mUpdateResizeBoundsCallback.accept(mLastResizeBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index 9c1e321..ac670cf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -33,7 +33,7 @@
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipUtils;
@@ -162,6 +162,18 @@
* @param configAtEnd true if we are delaying config updates until the transition ends.
*/
public void scheduleAnimateResizePip(Rect toBounds, boolean configAtEnd) {
+ scheduleAnimateResizePip(toBounds, configAtEnd,
+ PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION);
+ }
+
+ /**
+ * Animates resizing of the pinned stack given the duration.
+ *
+ * @param configAtEnd true if we are delaying config updates until the transition ends.
+ * @param duration the suggested duration to run the animation; the component responsible
+ * for running the animator will get this as an extra.
+ */
+ public void scheduleAnimateResizePip(Rect toBounds, boolean configAtEnd, int duration) {
if (mPipTransitionState.mPipTaskToken == null || !mPipTransitionState.isInPip()) {
return;
}
@@ -170,7 +182,7 @@
if (configAtEnd) {
wct.deferConfigToTransitionEnd(mPipTransitionState.mPipTaskToken);
}
- mPipTransitionController.startResizeTransition(wct);
+ mPipTransitionController.startResizeTransition(wct, duration);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 56a465a..0c4ed26 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -51,7 +51,7 @@
import android.view.accessibility.AccessibilityWindowInfo;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
@@ -713,15 +713,13 @@
}
}
- private void animateToMaximizedState(Runnable callback) {
- Rect maxMovementBounds = new Rect();
+ private void animateToMaximizedState() {
Rect maxBounds = new Rect(0, 0, mPipBoundsState.getMaxSize().x,
mPipBoundsState.getMaxSize().y);
- mPipBoundsAlgorithm.getMovementBounds(maxBounds, mInsetBounds, maxMovementBounds,
- mIsImeShowing ? mImeHeight : 0);
+
mSavedSnapFraction = mMotionHelper.animateToExpandedState(maxBounds,
- mPipBoundsState.getMovementBounds(), maxMovementBounds,
- callback);
+ getMovementBounds(mPipBoundsState.getBounds()),
+ getMovementBounds(maxBounds), null /* callback */);
}
private void animateToNormalSize(Runnable callback) {
@@ -729,22 +727,20 @@
mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
final Size minMenuSize = mMenuController.getEstimatedMinMenuSize();
- final Rect normalBounds = mPipBoundsState.getNormalBounds();
- final Rect destBounds = mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds,
- minMenuSize);
- Rect restoredMovementBounds = new Rect();
- mPipBoundsAlgorithm.getMovementBounds(destBounds,
- mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
- mSavedSnapFraction = mMotionHelper.animateToExpandedState(destBounds,
- mPipBoundsState.getMovementBounds(), restoredMovementBounds, callback);
+ final Size defaultSize = mSizeSpecSource.getDefaultSize(mPipBoundsState.getAspectRatio());
+ final Rect normalBounds = new Rect(0, 0, defaultSize.getWidth(), defaultSize.getHeight());
+ final Rect adjustedNormalBounds = mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(
+ normalBounds, minMenuSize);
+
+ mSavedSnapFraction = mMotionHelper.animateToExpandedState(adjustedNormalBounds,
+ getMovementBounds(mPipBoundsState.getBounds()),
+ getMovementBounds(adjustedNormalBounds), callback /* callback */);
}
private void animateToUnexpandedState(Rect restoreBounds) {
- Rect restoredMovementBounds = new Rect();
- mPipBoundsAlgorithm.getMovementBounds(restoreBounds,
- mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
- restoredMovementBounds, mPipBoundsState.getMovementBounds(), false /* immediate */);
+ getMovementBounds(restoreBounds),
+ getMovementBounds(mPipBoundsState.getBounds()), false /* immediate */);
mSavedSnapFraction = -1f;
}
@@ -919,10 +915,6 @@
&& mMenuState != MENU_STATE_FULL) {
// If using pinch to zoom, double-tap functions as resizing between max/min size
if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
- final boolean toExpand = mPipBoundsState.getBounds().width()
- < mPipBoundsState.getMaxSize().x
- && mPipBoundsState.getBounds().height()
- < mPipBoundsState.getMaxSize().y;
if (mMenuController.isMenuVisible()) {
mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
}
@@ -934,7 +926,7 @@
// actually toggle to the size chosen
if (nextSize == PipDoubleTapHelper.SIZE_SPEC_MAX) {
mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
- animateToMaximizedState(null);
+ animateToMaximizedState();
} else if (nextSize == PipDoubleTapHelper.SIZE_SPEC_DEFAULT) {
mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
animateToNormalSize(null);
@@ -1045,7 +1037,9 @@
private Rect getMovementBounds(Rect curBounds) {
Rect movementBounds = new Rect();
- mPipBoundsAlgorithm.getMovementBounds(curBounds, mInsetBounds,
+ Rect insetBounds = new Rect();
+ mPipBoundsAlgorithm.getInsetBounds(insetBounds);
+ mPipBoundsAlgorithm.getMovementBounds(curBounds, insetBounds,
movementBounds, mIsImeShowing ? mImeHeight : 0);
return movementBounds;
}
@@ -1091,6 +1085,7 @@
case PipTransitionState.ENTERED_PIP:
onActivityPinned();
mTouchState.setAllowInputEvents(true);
+ mTouchState.reset();
break;
case PipTransitionState.EXITED_PIP:
mTouchState.setAllowInputEvents(false);
@@ -1101,6 +1096,7 @@
break;
case PipTransitionState.CHANGED_PIP_BOUNDS:
mTouchState.setAllowInputEvents(true);
+ mTouchState.reset();
break;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
index d093f1e..bb8d4ee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
@@ -23,7 +23,7 @@
import android.view.ViewConfiguration;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 57dc5f9..683d30d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -71,6 +71,9 @@
static final String PIP_START_TX = "pip_start_tx";
static final String PIP_FINISH_TX = "pip_finish_tx";
static final String PIP_DESTINATION_BOUNDS = "pip_dest_bounds";
+ static final String ANIMATING_BOUNDS_CHANGE_DURATION =
+ "animating_bounds_change_duration";
+ static final int BOUNDS_CHANGE_JUMPCUT_DURATION = 0;
/**
* The fixed start delay in ms when fading out the content overlay from bounds animation.
@@ -87,7 +90,7 @@
private final PipTransitionState mPipTransitionState;
//
- // Transition tokens
+ // Transition caches
//
@Nullable
@@ -96,6 +99,8 @@
private IBinder mExitViaExpandTransition;
@Nullable
private IBinder mResizeTransition;
+ private int mBoundsChangeDuration = BOUNDS_CHANGE_JUMPCUT_DURATION;
+
//
// Internal state and relevant cached info
@@ -152,11 +157,12 @@
}
@Override
- public void startResizeTransition(WindowContainerTransaction wct) {
+ public void startResizeTransition(WindowContainerTransaction wct, int duration) {
if (wct == null) {
return;
}
mResizeTransition = mTransitions.startTransition(TRANSIT_RESIZE_PIP, wct, this);
+ mBoundsChangeDuration = duration;
}
@Nullable
@@ -272,6 +278,10 @@
extra.putParcelable(PIP_START_TX, startTransaction);
extra.putParcelable(PIP_FINISH_TX, finishTransaction);
extra.putParcelable(PIP_DESTINATION_BOUNDS, pipChange.getEndAbsBounds());
+ if (mBoundsChangeDuration > BOUNDS_CHANGE_JUMPCUT_DURATION) {
+ extra.putInt(ANIMATING_BOUNDS_CHANGE_DURATION, mBoundsChangeDuration);
+ mBoundsChangeDuration = BOUNDS_CHANGE_JUMPCUT_DURATION;
+ }
mFinishCallback = finishCallback;
mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index 9d599ca..29272be 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -29,6 +29,7 @@
import com.android.internal.util.Preconditions;
import com.android.wm.shell.shared.annotations.ShellMainThread;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -62,6 +63,8 @@
* and throw an <code>IllegalStateException</code> otherwise.</p>
*/
public class PipTransitionState {
+ private static final String TAG = PipTransitionState.class.getSimpleName();
+
public static final int UNDEFINED = 0;
// State for Launcher animating the swipe PiP to home animation.
@@ -190,8 +193,9 @@
"No extra bundle for " + stateToString(state) + " state.");
}
if (mState != state) {
- dispatchPipTransitionStateChanged(mState, state, extra);
+ final int prevState = mState;
mState = state;
+ dispatchPipTransitionStateChanged(prevState, mState, extra);
}
}
@@ -319,4 +323,11 @@
return String.format("PipTransitionState(mState=%s, mInSwipePipToHomeTransition=%b)",
stateToString(mState), mInSwipePipToHomeTransition);
}
+
+ /** Dumps internal state. */
+ public void dump(PrintWriter pw, String prefix) {
+ final String innerPrefix = prefix + " ";
+ pw.println(prefix + TAG);
+ pw.println(innerPrefix + "mState=" + stateToString(mState));
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index ad298dc..814eaae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -43,7 +43,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index c67cf1d..e46625d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -63,7 +63,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.IResultReceiver;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
index 7c5f10a..8ee72b4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
@@ -76,21 +76,40 @@
continue
}
+ // Filter out changes that we care about
if (change.mode == WindowManager.TRANSIT_OPEN) {
change.taskInfo?.let { taskInfoList.add(it) }
transitionTypeList.add(change.mode)
}
}
- transitionToTransitionChanges.put(
- transition,
- TransitionChanges(taskInfoList, transitionTypeList)
- )
+ // Only add the transition to map if it has a change we care about
+ if (taskInfoList.isNotEmpty()) {
+ transitionToTransitionChanges.put(
+ transition,
+ TransitionChanges(taskInfoList, transitionTypeList)
+ )
+ }
}
}
override fun onTransitionStarting(transition: IBinder) {}
- override fun onTransitionMerged(merged: IBinder, playing: IBinder) {}
+ override fun onTransitionMerged(merged: IBinder, playing: IBinder) {
+ val mergedTransitionChanges =
+ transitionToTransitionChanges.get(merged)
+ ?:
+ // We are adding changes of the merged transition to changes of the playing
+ // transition so if there is no changes nothing to do.
+ return
+
+ transitionToTransitionChanges.remove(merged)
+ val playingTransitionChanges = transitionToTransitionChanges.get(playing)
+ if (playingTransitionChanges != null) {
+ playingTransitionChanges.merge(mergedTransitionChanges)
+ } else {
+ transitionToTransitionChanges.put(playing, mergedTransitionChanges)
+ }
+ }
override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
val taskInfoList =
@@ -138,6 +157,11 @@
private data class TransitionChanges(
val taskInfoList: MutableList<RunningTaskInfo> = ArrayList(),
- val transitionTypeList: MutableList<Int> = ArrayList()
- )
+ val transitionTypeList: MutableList<Int> = ArrayList(),
+ ) {
+ fun merge(transitionChanges: TransitionChanges) {
+ taskInfoList.addAll(transitionChanges.taskInfoList)
+ transitionTypeList.addAll(transitionChanges.transitionTypeList)
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index 64e26db..1cbb8bb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -23,7 +23,7 @@
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.SyncTransactionQueue;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index f5fbae5..27fd309 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -24,7 +24,7 @@
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.SyncTransactionQueue;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index dd219d3..b4941a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -73,7 +73,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index 0541a02..b3dab85 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -46,7 +46,7 @@
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitDecorManager;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 45eff4a..d9e9776 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -119,7 +119,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 0f3d6ca..1076eca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -45,7 +45,7 @@
import androidx.annotation.NonNull;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.ShellTaskOrganizer;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java
index 1d8a8d5..e0f6394 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java
@@ -36,7 +36,7 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.split.SplitScreenConstants;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
index 6325c68..ea8c0eb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
@@ -390,7 +390,8 @@
SurfaceControl firstWindowSurface, ViewGroup splashScreenView,
TransactionPool transactionPool, Rect firstWindowFrame,
int mainWindowShiftLength, float roundedCornerRadius) {
- mFromYDelta = fromYDelta - Math.max(firstWindowFrame.top, roundedCornerRadius);
+ mFromYDelta = firstWindowFrame.top
+ - Math.max(firstWindowFrame.top, roundedCornerRadius);
mToYDelta = toYDelta;
mOccludeHoleView = occludeHoleView;
mApplier = new SyncRtSurfaceTransactionApplier(occludeHoleView);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 2b12a22..90eb22f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -74,7 +74,7 @@
import com.android.internal.graphics.palette.Quantizer;
import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
import com.android.internal.policy.PhoneWindow;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.common.TransactionPool;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index e552e6c..08211ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -53,7 +53,7 @@
import android.window.StartingWindowInfo;
import android.window.StartingWindowRemovalInfo;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ContrastColorUtil;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 3353c7b..97a695f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -43,7 +43,7 @@
import android.window.TaskSnapshot;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TransactionPool;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 8fc54ed..6e084d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -48,7 +48,7 @@
import android.window.StartingWindowInfo;
import android.window.TaskSnapshot;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.view.BaseIWindow;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
index 72fc8686..2036d9c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
@@ -35,7 +35,7 @@
import android.window.StartingWindowInfo;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
index 2e6ddc3..aa9f15c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
@@ -18,7 +18,7 @@
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.io.PrintWriter;
import java.util.Arrays;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
index 5ced1fb..0202b6c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
@@ -40,7 +40,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
import com.android.wm.shell.common.ExternalInterfaceBinder;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
index 2e2f569..3a68009 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
@@ -25,7 +25,7 @@
import androidx.annotation.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import java.util.ArrayList;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 8ee1efa..4f4b809 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -39,7 +39,7 @@
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
import com.android.wm.shell.common.split.SplitScreenUtils;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
index c33fb80..c8921d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
@@ -28,7 +28,7 @@
import android.view.SurfaceControl;
import android.window.TransitionInfo;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
import com.android.wm.shell.pip.PipTransitionController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 9412b2b..73b32a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -53,6 +53,7 @@
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
+import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CHANGE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CLOSE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_CLOSE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
@@ -102,7 +103,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.window.flags.Flags;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -944,12 +945,15 @@
}
private static int getWallpaperTransitType(TransitionInfo info) {
+ boolean hasWallpaper = false;
boolean hasOpenWallpaper = false;
boolean hasCloseWallpaper = false;
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
- if ((change.getFlags() & FLAG_SHOW_WALLPAPER) != 0) {
+ if ((change.getFlags() & FLAG_SHOW_WALLPAPER) != 0
+ || (change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
+ hasWallpaper = true;
if (TransitionUtil.isOpeningType(change.getMode())) {
hasOpenWallpaper = true;
} else if (TransitionUtil.isClosingType(change.getMode())) {
@@ -965,6 +969,8 @@
return WALLPAPER_TRANSITION_OPEN;
} else if (hasCloseWallpaper) {
return WALLPAPER_TRANSITION_CLOSE;
+ } else if (hasWallpaper) {
+ return WALLPAPER_TRANSITION_CHANGE;
} else {
return WALLPAPER_TRANSITION_NONE;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
index 89b0e25..978b8da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
@@ -28,7 +28,7 @@
import android.view.WindowManager;
import android.window.IWindowContainerTransactionCallback;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
/**
* Utilities and interfaces for transition-like usage on top of the legacy app-transition and
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
index e8b01b5..8cc7f21 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
@@ -35,7 +35,7 @@
import android.view.SurfaceControl;
import android.window.TransitionInfo;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -184,7 +184,8 @@
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
TransitionInfo.Change change = info.getChanges().get(i);
- if (change == pipChange || !isOpeningMode(change.getMode())) {
+ if (change == pipChange || !isOpeningMode(change.getMode()) ||
+ change.getTaskInfo() == null) {
// Ignore the change/task that's going into Pip or not opening
continue;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
index 69c4167..c5dc668 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
@@ -30,7 +30,7 @@
import android.window.WindowAnimationState;
import android.window.WindowContainerTransaction;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
index 9fc6702..391c5fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
@@ -30,7 +30,7 @@
import android.window.TransitionInfo;
import android.window.WindowContainerTransaction;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
import com.android.wm.shell.pip.PipTransitionController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
index d686046..6013a1e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
@@ -39,7 +39,7 @@
import androidx.annotation.BinderThread;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.TransitionUtil;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index 2047b5a..a5f071a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -54,7 +54,7 @@
import com.android.internal.R;
import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.window.flags.Flags;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.TransitionUtil;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index d2760ff..ec6802d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -28,12 +28,15 @@
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
+import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
+import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
+import static com.android.window.flags.Flags.ensureWallpaperInTransitions;
import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary;
import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
@@ -72,7 +75,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -519,12 +522,17 @@
boolean isOpening = isOpeningType(info.getType());
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
- if (change.hasFlags(TransitionInfo.FLAGS_IS_NON_APP_WINDOW)) {
+ if (change.hasFlags(FLAGS_IS_NON_APP_WINDOW & ~FLAG_IS_WALLPAPER)) {
// Currently system windows are controlled by WindowState, so don't change their
// surfaces. Otherwise their surfaces could be hidden or cropped unexpectedly.
- // This includes Wallpaper (always z-ordered at bottom) and IME (associated with
- // app), because there may not be a transition associated with their visibility
- // changes, and currently they don't need transition animation.
+ // This includes IME (associated with app), because there may not be a transition
+ // associated with their visibility changes, and currently they don't need a
+ // transition animation.
+ continue;
+ }
+ if (change.hasFlags(FLAG_IS_WALLPAPER) && !ensureWallpaperInTransitions()) {
+ // Wallpaper is always z-ordered at bottom, and historically is not animated by
+ // transition handlers.
continue;
}
final SurfaceControl leash = change.getLeash();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index 7c2ba45..88bfebf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -33,7 +33,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.sysui.ShellInit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
index 564e716..ee6c81a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
@@ -18,10 +18,10 @@
import android.util.Log
import com.android.internal.protolog.common.IProtoLogGroup
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
/**
- * Log messages using an API similar to [com.android.internal.protolog.common.ProtoLog]. Useful for
+ * Log messages using an API similar to [com.android.internal.protolog.ProtoLog]. Useful for
* logging from Kotlin classes as ProtoLog does not have support for Kotlin.
*
* All messages are logged to logcat if logging is enabled for that [IProtoLogGroup].
@@ -29,42 +29,42 @@
// TODO(b/168581922): remove once ProtoLog adds support for Kotlin
class KtProtoLog {
companion object {
- /** @see [com.android.internal.protolog.common.ProtoLog.d] */
+ /** @see [com.android.internal.protolog.ProtoLog.d] */
fun d(group: IProtoLogGroup, messageString: String, vararg args: Any) {
if (group.isLogToLogcat) {
Log.d(group.tag, String.format(messageString, *args))
}
}
- /** @see [com.android.internal.protolog.common.ProtoLog.v] */
+ /** @see [com.android.internal.protolog.ProtoLog.v] */
fun v(group: IProtoLogGroup, messageString: String, vararg args: Any) {
if (group.isLogToLogcat) {
Log.v(group.tag, String.format(messageString, *args))
}
}
- /** @see [com.android.internal.protolog.common.ProtoLog.i] */
+ /** @see [com.android.internal.protolog.ProtoLog.i] */
fun i(group: IProtoLogGroup, messageString: String, vararg args: Any) {
if (group.isLogToLogcat) {
Log.i(group.tag, String.format(messageString, *args))
}
}
- /** @see [com.android.internal.protolog.common.ProtoLog.w] */
+ /** @see [com.android.internal.protolog.ProtoLog.w] */
fun w(group: IProtoLogGroup, messageString: String, vararg args: Any) {
if (group.isLogToLogcat) {
Log.w(group.tag, String.format(messageString, *args))
}
}
- /** @see [com.android.internal.protolog.common.ProtoLog.e] */
+ /** @see [com.android.internal.protolog.ProtoLog.e] */
fun e(group: IProtoLogGroup, messageString: String, vararg args: Any) {
if (group.isLogToLogcat) {
Log.e(group.tag, String.format(messageString, *args))
}
}
- /** @see [com.android.internal.protolog.common.ProtoLog.wtf] */
+ /** @see [com.android.internal.protolog.ProtoLog.wtf] */
fun wtf(group: IProtoLogGroup, messageString: String, vararg args: Any) {
if (group.isLogToLogcat) {
Log.wtf(group.tag, String.format(messageString, *args))
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/util/OWNERS
new file mode 100644
index 0000000..482aaab
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/OWNERS
@@ -0,0 +1 @@
+per-file KtProtolog.kt = file:platform/development:/tools/winscope/OWNERS
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index e1009a0..e3aa31f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -26,7 +26,6 @@
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_HOVER_ENTER;
import static android.view.MotionEvent.ACTION_HOVER_EXIT;
-import static android.view.MotionEvent.ACTION_HOVER_MOVE;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowInsets.Type.statusBars;
@@ -74,7 +73,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.Cuj;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.protolog.ProtoLog;
import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
@@ -82,7 +82,6 @@
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource;
@@ -103,6 +102,7 @@
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
+import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
import java.io.PrintWriter;
import java.util.Objects;
@@ -131,6 +131,7 @@
private final SyncTransactionQueue mSyncQueue;
private final DesktopTasksController mDesktopTasksController;
private final InputManager mInputManager;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -186,7 +187,8 @@
SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopTasksController> desktopTasksController,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ InteractionJankMonitor interactionJankMonitor
) {
this(
context,
@@ -207,7 +209,8 @@
new InputMonitorFactory(),
SurfaceControl.Transaction::new,
rootTaskDisplayAreaOrganizer,
- new SparseArray<>());
+ new SparseArray<>(),
+ interactionJankMonitor);
}
@VisibleForTesting
@@ -230,7 +233,8 @@
InputMonitorFactory inputMonitorFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
- SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId) {
+ SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId,
+ InteractionJankMonitor interactionJankMonitor) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -253,6 +257,7 @@
mWindowDecorByTaskId = windowDecorByTaskId;
mSysUIPackageName = mContext.getResources().getString(
com.android.internal.R.string.config_systemUi);
+ mInteractionJankMonitor = interactionJankMonitor;
shellInit.addInitCallback(this::onInit, this);
}
@@ -383,10 +388,32 @@
mWindowDecorByTaskId.remove(taskInfo.taskId);
}
+ private void onMaximizeOrRestore(int taskId, String tag) {
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+ if (decoration == null) {
+ return;
+ }
+ mInteractionJankMonitor.begin(
+ decoration.mTaskSurface, mContext, Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, tag);
+ mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
+ decoration.closeHandleMenu();
+ decoration.closeMaximizeMenu();
+ }
+
+ private void onSnapResize(int taskId, boolean left) {
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+ if (decoration == null) {
+ return;
+ }
+ mDesktopTasksController.snapToHalfScreen(decoration.mTaskInfo,
+ left ? SnapPosition.LEFT : SnapPosition.RIGHT);
+ decoration.closeHandleMenu();
+ decoration.closeMaximizeMenu();
+ }
+
private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
View.OnGenericMotionListener, DragDetector.MotionEventHandler {
- private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150;
private final int mTaskId;
private final WindowContainerToken mTaskToken;
@@ -405,7 +432,6 @@
private boolean mTouchscreenInUse;
private boolean mHasLongClicked;
private int mDragPointerId = -1;
- private final Runnable mCloseMaximizeWindowRunnable;
private DesktopModeTouchEventListener(
RunningTaskInfo taskInfo,
@@ -416,11 +442,6 @@
mDragDetector = new DragDetector(this);
mGestureDetector = new GestureDetector(mContext, this);
mDisplayId = taskInfo.displayId;
- mCloseMaximizeWindowRunnable = () -> {
- final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
- if (decoration == null) return;
- decoration.closeMaximizeMenu();
- };
}
@Override
@@ -472,31 +493,12 @@
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
} else if (id == R.id.maximize_window) {
- InteractionJankMonitorUtils.beginTracing(
- Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, /* view= */ v,
- /* tag= */ "caption_bar_button");
- final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- decoration.closeHandleMenu();
- decoration.closeMaximizeMenu();
- mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
- } else if (id == R.id.maximize_menu_maximize_button) {
- InteractionJankMonitorUtils.beginTracing(
- Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, /* view= */ v,
- /* tag= */ "maximize_menu_option");
- final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
- decoration.closeHandleMenu();
- decoration.closeMaximizeMenu();
- } else if (id == R.id.maximize_menu_snap_left_button) {
- final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.LEFT);
- decoration.closeHandleMenu();
- decoration.closeMaximizeMenu();
- } else if (id == R.id.maximize_menu_snap_right_button) {
- final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.RIGHT);
- decoration.closeHandleMenu();
- decoration.closeMaximizeMenu();
+ // TODO(b/346441962): move click detection logic into the decor's
+ // {@link AppHeaderViewHolder}. Let it encapsulate the that and have it report
+ // back to the decoration using
+ // {@link DesktopModeWindowDecoration#setOnMaximizeOrRestoreClickListener}, which
+ // should shared with the maximize menu's maximize/restore actions.
+ onMaximizeOrRestore(decoration.mTaskInfo.taskId, "caption_bar_button");
}
}
@@ -578,40 +580,26 @@
return false;
}
+ /**
+ * TODO(b/346441962): move this hover detection logic into the decor's
+ * {@link AppHeaderViewHolder}.
+ */
@Override
public boolean onGenericMotion(View v, MotionEvent ev) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
final int id = v.getId();
- if (ev.getAction() == ACTION_HOVER_ENTER) {
- if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
- decoration.onMaximizeWindowHoverEnter();
- } else if (id == R.id.maximize_window
- || MaximizeMenu.Companion.isMaximizeMenuView(id)) {
- // Re-hovering over any of the maximize menu views should keep the menu open by
- // cancelling any attempts to close the menu.
- mMainHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
- if (id != R.id.maximize_window) {
- decoration.onMaximizeMenuHoverEnter(id, ev);
- }
+ if (ev.getAction() == ACTION_HOVER_ENTER && id == R.id.maximize_window) {
+ decoration.setAppHeaderMaximizeButtonHovered(true);
+ if (!decoration.isMaximizeMenuActive()) {
+ decoration.onMaximizeButtonHoverEnter();
}
return true;
- } else if (ev.getAction() == ACTION_HOVER_MOVE
- && MaximizeMenu.Companion.isMaximizeMenuView(id)) {
- decoration.onMaximizeMenuHoverMove(id, ev);
- mMainHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
- } else if (ev.getAction() == ACTION_HOVER_EXIT) {
- if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
- decoration.onMaximizeWindowHoverExit();
- } else if (id == R.id.maximize_window
- || MaximizeMenu.Companion.isMaximizeMenuView(id)) {
- // Close menu if not hovering over maximize menu or maximize button after a
- // delay to give user a chance to re-enter view or to move from one maximize
- // menu view to another.
- mMainHandler.postDelayed(mCloseMaximizeWindowRunnable,
- CLOSE_MAXIMIZE_MENU_DELAY_MS);
- if (id != R.id.maximize_window) {
- decoration.onMaximizeMenuHoverExit(id, ev);
- }
+ }
+ if (ev.getAction() == ACTION_HOVER_EXIT && id == R.id.maximize_window) {
+ decoration.setAppHeaderMaximizeButtonHovered(false);
+ decoration.onMaximizeHoverStateChanged();
+ if (!decoration.isMaximizeMenuActive()) {
+ decoration.onMaximizeButtonHoverExit();
}
return true;
}
@@ -719,11 +707,7 @@
&& action != MotionEvent.ACTION_CANCEL)) {
return false;
}
- final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
- InteractionJankMonitorUtils.beginTracing(
- Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, mContext,
- /* surface= */ decoration.mTaskSurface, /* tag= */ "double_tap");
- mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
+ onMaximizeOrRestore(mTaskId, "double_tap");
return true;
}
}
@@ -1098,14 +1082,20 @@
} else {
dragPositioningCallback = new VeiledResizeTaskPositioner(
mTaskOrganizer, windowDecoration, mDisplayController,
- mDragStartListener, mTransitions);
+ mDragStartListener, mTransitions, mInteractionJankMonitor);
windowDecoration.setTaskDragResizer(
(VeiledResizeTaskPositioner) dragPositioningCallback);
}
final DesktopModeTouchEventListener touchEventListener =
new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback);
-
+ windowDecoration.setOnMaximizeOrRestoreClickListener(this::onMaximizeOrRestore);
+ windowDecoration.setOnLeftSnapClickListener((taskId, tag) -> {
+ onSnapResize(taskId, true /* isLeft */);
+ });
+ windowDecoration.setOnRightSnapClickListener((taskId, tag) -> {
+ onSnapResize(taskId, false /* isLeft */);
+ });
windowDecoration.setCaptionListeners(
touchEventListener, touchEventListener, touchEventListener, touchEventListener);
windowDecoration.setExclusionRegionListener(mExclusionRegionListener);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 4d597ca..2a95fa3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -31,6 +31,7 @@
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.WindowConfiguration.WindowingMode;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -69,6 +70,7 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
@@ -87,6 +89,9 @@
public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
private static final String TAG = "DesktopModeWindowDecoration";
+ @VisibleForTesting
+ static final long CLOSE_MAXIMIZE_MENU_DELAY_MS = 150L;
+
private final Handler mHandler;
private final Choreographer mChoreographer;
private final SyncTransactionQueue mSyncQueue;
@@ -96,6 +101,9 @@
private View.OnTouchListener mOnCaptionTouchListener;
private View.OnLongClickListener mOnCaptionLongClickListener;
private View.OnGenericMotionListener mOnCaptionGenericMotionListener;
+ private OnTaskActionClickListener mOnMaximizeOrRestoreClickListener;
+ private OnTaskActionClickListener mOnLeftSnapClickListener;
+ private OnTaskActionClickListener mOnRightSnapClickListener;
private DragPositioningCallback mDragPositioningCallback;
private DragResizeInputListener mDragResizeListener;
private DragDetector mDragDetector;
@@ -120,6 +128,16 @@
private ExclusionRegionListener mExclusionRegionListener;
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+ private final MaximizeMenuFactory mMaximizeMenuFactory;
+
+ // Hover state for the maximize menu and button. The menu will remain open as long as either of
+ // these is true. See {@link #onMaximizeHoverStateChanged()}.
+ private boolean mIsAppHeaderMaximizeButtonHovered = false;
+ private boolean mIsMaximizeMenuHovered = false;
+ // Used to schedule the closing of the maximize menu when neither of the button or menu are
+ // being hovered. There's a small delay after stopping the hover, to allow a quick reentry
+ // to cancel the close.
+ private final Runnable mCloseMaximizeWindowRunnable = this::closeMaximizeMenu;
DesktopModeWindowDecoration(
Context context,
@@ -135,7 +153,8 @@
handler, choreographer, syncQueue, rootTaskDisplayAreaOrganizer,
SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
WindowContainerTransaction::new, SurfaceControl::new,
- new SurfaceControlViewHostFactory() {});
+ new SurfaceControlViewHostFactory() {},
+ DefaultMaximizeMenuFactory.INSTANCE);
}
DesktopModeWindowDecoration(
@@ -152,7 +171,8 @@
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
Supplier<SurfaceControl> surfaceControlSupplier,
- SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
+ SurfaceControlViewHostFactory surfaceControlViewHostFactory,
+ MaximizeMenuFactory maximizeMenuFactory) {
super(context, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlSupplier,
@@ -161,6 +181,31 @@
mChoreographer = choreographer;
mSyncQueue = syncQueue;
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+ mMaximizeMenuFactory = maximizeMenuFactory;
+ }
+
+ /**
+ * Register a listener to be called back when one of the tasks' maximize/restore action is
+ * triggered.
+ * TODO(b/346441962): hook this up to double-tap and the header's maximize button, instead of
+ * having the ViewModel deal with parsing motion events.
+ */
+ void setOnMaximizeOrRestoreClickListener(OnTaskActionClickListener listener) {
+ mOnMaximizeOrRestoreClickListener = listener;
+ }
+
+ /**
+ * Register a listener to be called back when one of the tasks snap-left action is triggered.
+ */
+ void setOnLeftSnapClickListener(OnTaskActionClickListener listener) {
+ mOnLeftSnapClickListener = listener;
+ }
+
+ /**
+ * Register a listener to be called back when one of the tasks' snap-right action is triggered.
+ */
+ void setOnRightSnapClickListener(OnTaskActionClickListener listener) {
+ mOnRightSnapClickListener = listener;
}
void setCaptionListeners(
@@ -556,12 +601,13 @@
if (mAppIconBitmap != null && mAppName != null) {
return;
}
- final ActivityInfo activityInfo = mTaskInfo.topActivityInfo;
- if (activityInfo == null) {
- Log.e(TAG, "Top activity info not found in task");
+ final ComponentName baseActivity = mTaskInfo.baseActivity;
+ if (baseActivity == null) {
+ Log.e(TAG, "Base activity component not found in task");
return;
}
- PackageManager pm = mContext.getApplicationContext().getPackageManager();
+ final PackageManager pm = mContext.getApplicationContext().getPackageManager();
+ final ActivityInfo activityInfo = pm.getActivityInfo(baseActivity, 0 /* flags */);
final IconProvider provider = new IconProvider(mContext);
final Drawable appIconDrawable = provider.getIcon(activityInfo);
final BaseIconFactory headerIconFactory = createIconFactory(mContext,
@@ -575,6 +621,8 @@
final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
mAppName = pm.getApplicationLabel(applicationInfo);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Base activity's component name cannot be found on the system");
} finally {
Trace.endSection();
}
@@ -714,11 +762,41 @@
* Create and display maximize menu window
*/
void createMaximizeMenu() {
- mMaximizeMenu = new MaximizeMenu(mSyncQueue, mRootTaskDisplayAreaOrganizer,
- mDisplayController, mTaskInfo, mOnCaptionButtonClickListener,
- mOnCaptionGenericMotionListener, mOnCaptionTouchListener, mContext,
+ mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer,
+ mDisplayController, mTaskInfo, mContext,
calculateMaximizeMenuPosition(), mSurfaceControlTransactionSupplier);
- mMaximizeMenu.show();
+ mMaximizeMenu.show(
+ mOnMaximizeOrRestoreClickListener,
+ mOnLeftSnapClickListener,
+ mOnRightSnapClickListener,
+ hovered -> {
+ mIsMaximizeMenuHovered = hovered;
+ onMaximizeHoverStateChanged();
+ return null;
+ }
+ );
+ }
+
+ /** Set whether the app header's maximize button is hovered. */
+ void setAppHeaderMaximizeButtonHovered(boolean hovered) {
+ mIsAppHeaderMaximizeButtonHovered = hovered;
+ onMaximizeHoverStateChanged();
+ }
+
+ /**
+ * Called when either one of the maximize button in the app header or the maximize menu has
+ * changed its hover state.
+ */
+ void onMaximizeHoverStateChanged() {
+ if (!mIsMaximizeMenuHovered && !mIsAppHeaderMaximizeButtonHovered) {
+ // Neither is hovered, close the menu.
+ if (isMaximizeMenuActive()) {
+ mHandler.postDelayed(mCloseMaximizeWindowRunnable, CLOSE_MAXIMIZE_MENU_DELAY_MS);
+ }
+ return;
+ }
+ // At least one of the two is hovered, cancel the close if needed.
+ mHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
}
/**
@@ -992,34 +1070,22 @@
.setAnimatingTaskResize(animatingTaskResize);
}
- /** Called when there is a {@Link ACTION_HOVER_EXIT} on the maximize window button. */
- void onMaximizeWindowHoverExit() {
+ /**
+ * Called when there is a {@link MotionEvent#ACTION_HOVER_EXIT} on the maximize window button.
+ */
+ void onMaximizeButtonHoverExit() {
((AppHeaderViewHolder) mWindowDecorViewHolder)
.onMaximizeWindowHoverExit();
}
- /** Called when there is a {@Link ACTION_HOVER_ENTER} on the maximize window button. */
- void onMaximizeWindowHoverEnter() {
+ /**
+ * Called when there is a {@link MotionEvent#ACTION_HOVER_ENTER} on the maximize window button.
+ */
+ void onMaximizeButtonHoverEnter() {
((AppHeaderViewHolder) mWindowDecorViewHolder)
.onMaximizeWindowHoverEnter();
}
- /** Called when there is a {@Link ACTION_HOVER_ENTER} on a view in the maximize menu. */
- void onMaximizeMenuHoverEnter(int id, MotionEvent ev) {
- mMaximizeMenu.onMaximizeMenuHoverEnter(id, ev);
- }
-
- /** Called when there is a {@Link ACTION_HOVER_MOVE} on a view in the maximize menu. */
- void onMaximizeMenuHoverMove(int id, MotionEvent ev) {
- mMaximizeMenu.onMaximizeMenuHoverMove(id, ev);
- }
-
- /** Called when there is a {@Link ACTION_HOVER_EXIT} on a view in the maximize menu. */
- void onMaximizeMenuHoverExit(int id, MotionEvent ev) {
- mMaximizeMenu.onMaximizeMenuHoverExit(id, ev);
- }
-
-
@Override
public String toString() {
return "{"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index d902444..a3616f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -55,7 +55,7 @@
import android.view.WindowManagerGlobal;
import android.window.InputTransferToken;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index 0470367..5f9f8d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -20,7 +20,6 @@
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.annotation.ColorInt
-import android.annotation.IdRes
import android.app.ActivityManager.RunningTaskInfo
import android.content.Context
import android.content.res.ColorStateList
@@ -28,6 +27,7 @@
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.PointF
+import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.LayerDrawable
@@ -37,16 +37,17 @@
import android.util.StateSet
import android.view.LayoutInflater
import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_HOVER_ENTER
+import android.view.MotionEvent.ACTION_HOVER_EXIT
+import android.view.MotionEvent.ACTION_HOVER_MOVE
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import android.view.SurfaceControlViewHost
import android.view.View
-import android.view.View.OnClickListener
-import android.view.View.OnGenericMotionListener
-import android.view.View.OnTouchListener
import android.view.View.SCALE_Y
import android.view.View.TRANSLATION_Y
import android.view.View.TRANSLATION_Z
+import android.view.ViewGroup
import android.view.WindowManager
import android.view.WindowlessWindowManager
import android.widget.Button
@@ -64,10 +65,10 @@
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
import com.android.wm.shell.windowdecor.common.OPACITY_12
import com.android.wm.shell.windowdecor.common.OPACITY_40
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener
import com.android.wm.shell.windowdecor.common.withAlpha
import java.util.function.Supplier
-
/**
* Menu that appears when user long clicks the maximize button. Gives the user the option to
* maximize the task or snap the task to the right or left half of the screen.
@@ -77,9 +78,6 @@
private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
private val displayController: DisplayController,
private val taskInfo: RunningTaskInfo,
- private val onClickListener: OnClickListener,
- private val onGenericMotionListener: OnGenericMotionListener,
- private val onTouchListener: OnTouchListener,
private val decorWindowContext: Context,
private val menuPosition: PointF,
private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }
@@ -102,9 +100,19 @@
}
/** Creates and shows the maximize window. */
- fun show() {
+ fun show(
+ onMaximizeClickListener: OnTaskActionClickListener,
+ onLeftSnapClickListener: OnTaskActionClickListener,
+ onRightSnapClickListener: OnTaskActionClickListener,
+ onHoverListener: (Boolean) -> Unit
+ ) {
if (maximizeMenu != null) return
- createMaximizeMenu()
+ createMaximizeMenu(
+ onMaximizeClickListener = onMaximizeClickListener,
+ onLeftSnapClickListener = onLeftSnapClickListener,
+ onRightSnapClickListener = onRightSnapClickListener,
+ onHoverListener = onHoverListener
+ )
maximizeMenuView?.animateOpenMenu()
}
@@ -117,7 +125,12 @@
}
/** Create a maximize menu that is attached to the display area. */
- private fun createMaximizeMenu() {
+ private fun createMaximizeMenu(
+ onMaximizeClickListener: OnTaskActionClickListener,
+ onLeftSnapClickListener: OnTaskActionClickListener,
+ onRightSnapClickListener: OnTaskActionClickListener,
+ onHoverListener: (Boolean) -> Unit
+ ) {
val t = transactionSupplier.get()
val builder = SurfaceControl.Builder()
rootTdaOrganizer.attachToDisplayArea(taskInfo.displayId, builder)
@@ -146,11 +159,19 @@
context = decorWindowContext,
menuHeight = menuHeight,
menuPadding = menuPadding,
- onClickListener = onClickListener,
- onTouchListener = onTouchListener,
- onGenericMotionListener = onGenericMotionListener,
).also { menuView ->
+ val taskId = taskInfo.taskId
menuView.bind(taskInfo)
+ menuView.onMaximizeClickListener = {
+ onMaximizeClickListener.onClick(taskId, "maximize_menu_option")
+ }
+ menuView.onLeftSnapClickListener = {
+ onLeftSnapClickListener.onClick(taskId, "left_snap_option")
+ }
+ menuView.onRightSnapClickListener = {
+ onRightSnapClickListener.onClick(taskId, "right_snap_option")
+ }
+ menuView.onMenuHoverListener = onHoverListener
viewHost.setView(menuView.rootView, lp)
}
@@ -198,56 +219,6 @@
}
/**
- * Called when a [MotionEvent.ACTION_HOVER_ENTER] is triggered on any of the menu's views.
- *
- * TODO(b/346440693): this is only needed for the left/right snap options that don't support
- * selector states to manage its hover state. Look into whether that can be added to avoid
- * manually tracking hover enter/exit motion events. Also because those button colors/states
- * aren't updating correctly for pressed, focused and selected states.
- * See also [onMaximizeMenuHoverMove] and [onMaximizeMenuHoverExit].
- */
- fun onMaximizeMenuHoverEnter(viewId: Int, ev: MotionEvent) {
- setSnapButtonsColorOnHover(viewId, ev)
- }
-
- /** Called when a [MotionEvent.ACTION_HOVER_MOVE] is triggered on any of the menu's views. */
- fun onMaximizeMenuHoverMove(viewId: Int, ev: MotionEvent) {
- setSnapButtonsColorOnHover(viewId, ev)
- }
-
- /** Called when a [MotionEvent.ACTION_HOVER_EXIT] is triggered on any of the menu's views. */
- fun onMaximizeMenuHoverExit(id: Int, ev: MotionEvent) {
- val snapOptionsWidth = maximizeMenuView?.snapOptionsWidth ?: return
- val snapOptionsHeight = maximizeMenuView?.snapOptionsHeight ?: return
- val inSnapMenuBounds = ev.x >= 0 && ev.x <= snapOptionsWidth &&
- ev.y >= 0 && ev.y <= snapOptionsHeight
-
- if (id == R.id.maximize_menu_snap_menu_layout && !inSnapMenuBounds) {
- // After exiting the snap menu layout area, checks to see that user is not still
- // hovering within the snap menu layout bounds which would indicate that the user is
- // hovering over a snap button within the snap menu layout rather than having exited.
- maximizeMenuView?.updateSplitSnapSelection(MaximizeMenuView.SnapToHalfSelection.NONE)
- }
- }
-
- private fun setSnapButtonsColorOnHover(viewId: Int, ev: MotionEvent) {
- val snapOptionsWidth = maximizeMenuView?.snapOptionsWidth ?: return
- val snapMenuCenter = snapOptionsWidth / 2
- when {
- viewId == R.id.maximize_menu_snap_left_button ||
- (viewId == R.id.maximize_menu_snap_menu_layout && ev.x <= snapMenuCenter) -> {
- maximizeMenuView
- ?.updateSplitSnapSelection(MaximizeMenuView.SnapToHalfSelection.LEFT)
- }
- viewId == R.id.maximize_menu_snap_right_button ||
- (viewId == R.id.maximize_menu_snap_menu_layout && ev.x > snapMenuCenter) -> {
- maximizeMenuView
- ?.updateSplitSnapSelection(MaximizeMenuView.SnapToHalfSelection.RIGHT)
- }
- }
- }
-
- /**
* The view within the Maximize Menu, presents maximize, restore and snap-to-side options for
* resizing a Task.
*/
@@ -255,12 +226,11 @@
context: Context,
private val menuHeight: Int,
private val menuPadding: Int,
- onClickListener: OnClickListener,
- onTouchListener: OnTouchListener,
- onGenericMotionListener: OnGenericMotionListener,
) {
- val rootView: View = LayoutInflater.from(context)
- .inflate(R.layout.desktop_mode_window_decor_maximize_menu, null /* root */)
+ val rootView = LayoutInflater.from(context)
+ .inflate(R.layout.desktop_mode_window_decor_maximize_menu, null /* root */) as ViewGroup
+ private val container = requireViewById(R.id.container)
+ private val overlay = requireViewById(R.id.maximize_menu_overlay)
private val maximizeText =
requireViewById(R.id.maximize_menu_maximize_window_text) as TextView
private val maximizeButton =
@@ -285,30 +255,63 @@
private val fillRadius = context.resources
.getDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_buttons_fill_radius)
+ private val hoverTempRect = Rect()
private val openMenuAnimatorSet = AnimatorSet()
private lateinit var taskInfo: RunningTaskInfo
private lateinit var style: MenuStyle
- /** The width of the snap menu option view, including both left and right snaps. */
- val snapOptionsWidth: Int
- get() = snapButtonsLayout.width
- /** The height of the snap menu option view, including both left and right snaps .*/
- val snapOptionsHeight: Int
- get() = snapButtonsLayout.height
+ /** Invoked when the maximize or restore option is clicked. */
+ var onMaximizeClickListener: (() -> Unit)? = null
+ /** Invoked when the left snap option is clicked. */
+ var onLeftSnapClickListener: (() -> Unit)? = null
+ /** Invoked when the right snap option is clicked. */
+ var onRightSnapClickListener: (() -> Unit)? = null
+ /** Invoked whenever the hover state of the menu changes. */
+ var onMenuHoverListener: ((Boolean) -> Unit)? = null
init {
- // TODO(b/346441962): encapsulate menu hover enter/exit logic inside this class and
- // expose only what is actually relevant to outside classes so that specific checks
- // against resource IDs aren't needed outside this class.
- rootView.setOnGenericMotionListener(onGenericMotionListener)
- rootView.setOnTouchListener(onTouchListener)
- maximizeButton.setOnClickListener(onClickListener)
- maximizeButton.setOnGenericMotionListener(onGenericMotionListener)
- snapRightButton.setOnClickListener(onClickListener)
- snapRightButton.setOnGenericMotionListener(onGenericMotionListener)
- snapLeftButton.setOnClickListener(onClickListener)
- snapLeftButton.setOnGenericMotionListener(onGenericMotionListener)
- snapButtonsLayout.setOnGenericMotionListener(onGenericMotionListener)
+ overlay.setOnHoverListener { _, event ->
+ // The overlay covers the entire menu, so it's a convenient way to monitor whether
+ // the menu is hovered as a whole or not.
+ when (event.action) {
+ ACTION_HOVER_ENTER -> onMenuHoverListener?.invoke(true)
+ ACTION_HOVER_EXIT -> onMenuHoverListener?.invoke(false)
+ }
+
+ // Also check if the hover falls within the snap options layout, to manually
+ // set the left/right state based on the event's position.
+ // TODO(b/346440693): this manual hover tracking is needed for left/right snap
+ // because its view/background(s) don't support selector states. Look into whether
+ // that can be added to avoid manual tracking. Also because these button
+ // colors/state logic is only being applied on hover events, but there's pressed,
+ // focused and selected states that should be responsive too.
+ val snapLayoutBoundsRelToOverlay = hoverTempRect.also { rect ->
+ snapButtonsLayout.getDrawingRect(rect)
+ rootView.offsetDescendantRectToMyCoords(snapButtonsLayout, rect)
+ }
+ if (event.action == ACTION_HOVER_ENTER || event.action == ACTION_HOVER_MOVE) {
+ if (snapLayoutBoundsRelToOverlay.contains(event.x.toInt(), event.y.toInt())) {
+ // Hover is inside the snap layout, anything left of center is the left
+ // snap, and anything right of center is right snap.
+ val layoutCenter = snapLayoutBoundsRelToOverlay.centerX()
+ if (event.x < layoutCenter) {
+ updateSplitSnapSelection(SnapToHalfSelection.LEFT)
+ } else {
+ updateSplitSnapSelection(SnapToHalfSelection.RIGHT)
+ }
+ } else {
+ // Any other hover is outside the snap layout, so neither is selected.
+ updateSplitSnapSelection(SnapToHalfSelection.NONE)
+ }
+ }
+
+ // Don't consume the event to allow child views to receive the event too.
+ return@setOnHoverListener false
+ }
+
+ maximizeButton.setOnClickListener { onMaximizeClickListener?.invoke() }
+ snapRightButton.setOnClickListener { onRightSnapClickListener?.invoke() }
+ snapLeftButton.setOnClickListener { onLeftSnapClickListener?.invoke() }
// To prevent aliasing.
maximizeButton.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
@@ -351,7 +354,7 @@
val value = animatedValue as Float
val topPadding = menuPadding -
((1 - value) * menuHeight).toInt()
- rootView.setPadding(menuPadding, topPadding,
+ container.setPadding(menuPadding, topPadding,
menuPadding, menuPadding)
}
},
@@ -410,7 +413,7 @@
}
/** Update the view state to a new snap to half selection. */
- fun updateSplitSnapSelection(selection: SnapToHalfSelection) {
+ private fun updateSplitSnapSelection(selection: SnapToHalfSelection) {
when (selection) {
SnapToHalfSelection.NONE -> deactivateSnapOptions()
SnapToHalfSelection.LEFT -> activateSnapOption(activateLeft = true)
@@ -638,13 +641,41 @@
private const val ELEVATION_ANIMATION_DURATION_MS = 50L
private const val CONTROLS_ALPHA_ANIMATION_DELAY_MS = 33L
private const val MENU_Z_TRANSLATION = 1f
- fun isMaximizeMenuView(@IdRes viewId: Int): Boolean {
- return viewId == R.id.maximize_menu ||
- viewId == R.id.maximize_menu_maximize_button ||
- viewId == R.id.maximize_menu_snap_left_button ||
- viewId == R.id.maximize_menu_snap_right_button ||
- viewId == R.id.maximize_menu_snap_menu_layout ||
- viewId == R.id.maximize_menu_snap_menu_layout
- }
+ }
+}
+
+/** A factory interface to create a [MaximizeMenu]. */
+interface MaximizeMenuFactory {
+ fun create(
+ syncQueue: SyncTransactionQueue,
+ rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
+ displayController: DisplayController,
+ taskInfo: RunningTaskInfo,
+ decorWindowContext: Context,
+ menuPosition: PointF,
+ transactionSupplier: Supplier<Transaction>
+ ): MaximizeMenu
+}
+
+/** A [MaximizeMenuFactory] implementation that creates a [MaximizeMenu]. */
+object DefaultMaximizeMenuFactory : MaximizeMenuFactory {
+ override fun create(
+ syncQueue: SyncTransactionQueue,
+ rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
+ displayController: DisplayController,
+ taskInfo: RunningTaskInfo,
+ decorWindowContext: Context,
+ menuPosition: PointF,
+ transactionSupplier: Supplier<Transaction>
+ ): MaximizeMenu {
+ return MaximizeMenu(
+ syncQueue,
+ rootTdaOrganizer,
+ displayController,
+ taskInfo,
+ decorWindowContext,
+ menuPosition,
+ transactionSupplier
+ )
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index 956d04c..1532211 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -33,9 +33,9 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.transition.Transitions;
import java.util.function.Supplier;
@@ -59,6 +59,7 @@
private final PointF mRepositionStartPoint = new PointF();
private final Rect mRepositionTaskBounds = new Rect();
private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private int mCtrlType;
private boolean mIsResizingOrAnimatingResize;
@Surface.Rotation private int mRotation;
@@ -67,22 +68,24 @@
DesktopModeWindowDecoration windowDecoration,
DisplayController displayController,
DragPositioningCallbackUtility.DragStartListener dragStartListener,
- Transitions transitions) {
+ Transitions transitions, InteractionJankMonitor interactionJankMonitor) {
this(taskOrganizer, windowDecoration, displayController, dragStartListener,
- SurfaceControl.Transaction::new, transitions);
+ SurfaceControl.Transaction::new, transitions, interactionJankMonitor);
}
public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
DesktopModeWindowDecoration windowDecoration,
DisplayController displayController,
DragPositioningCallbackUtility.DragStartListener dragStartListener,
- Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) {
+ Supplier<SurfaceControl.Transaction> supplier, Transitions transitions,
+ InteractionJankMonitor interactionJankMonitor) {
mDesktopWindowDecoration = windowDecoration;
mTaskOrganizer = taskOrganizer;
mDisplayController = displayController;
mDragStartListener = dragStartListener;
mTransactionSupplier = supplier;
mTransitions = transitions;
+ mInteractionJankMonitor = interactionJankMonitor;
}
@Override
@@ -93,9 +96,8 @@
mRepositionStartPoint.set(x, y);
if (isResizing()) {
// Capture CUJ for re-sizing window in DW mode.
- InteractionJankMonitorUtils.beginTracing(CUJ_DESKTOP_MODE_RESIZE_WINDOW,
- mDesktopWindowDecoration.mContext, mDesktopWindowDecoration.mTaskSurface,
- /* tag= */ null);
+ mInteractionJankMonitor.begin(mDesktopWindowDecoration.mTaskSurface,
+ mDesktopWindowDecoration.mContext, CUJ_DESKTOP_MODE_RESIZE_WINDOW);
if (!mDesktopWindowDecoration.mTaskInfo.isFocused) {
WindowContainerTransaction wct = new WindowContainerTransaction();
wct.reorder(mDesktopWindowDecoration.mTaskInfo.token, true);
@@ -153,7 +155,7 @@
// won't be called.
resetVeilIfVisible();
}
- InteractionJankMonitorUtils.endTracing(CUJ_DESKTOP_MODE_RESIZE_WINDOW);
+ mInteractionJankMonitor.end(CUJ_DESKTOP_MODE_RESIZE_WINDOW);
} else {
final WindowContainerTransaction wct = new WindowContainerTransaction();
DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/OnTaskActionClickListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/OnTaskActionClickListener.kt
new file mode 100644
index 0000000..14b9e7f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/OnTaskActionClickListener.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.windowdecor.common
+
+/** A callback to be invoked when a Task's window decor element is clicked. */
+fun interface OnTaskActionClickListener {
+ /**
+ * Called when a task's decor element has been clicked.
+ *
+ * @param taskId the id of the task.
+ * @param tag a readable identifier for the element.
+ */
+ fun onClick(taskId: Int, tag: String)
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
index 35ed8de..7873a85 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
@@ -65,7 +65,7 @@
setup {
standardAppHelper.launchViaIntent(
wmHelper,
- YouTubeAppHelper.getYoutubeVideoIntent("HPcEAtoXXLA"),
+ YouTubeAppHelper.getYoutubeVideoIntent("3KtWfp0UopM"),
ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
)
standardAppHelper.waitForVideoPlaying()
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
index 879034f..5c539a5 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
@@ -73,7 +73,7 @@
setup {
standardAppHelper.launchViaIntent(
wmHelper,
- YouTubeAppHelper.getYoutubeVideoIntent("HPcEAtoXXLA"),
+ YouTubeAppHelper.getYoutubeVideoIntent("3KtWfp0UopM"),
ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
)
standardAppHelper.enterFullscreen()
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
index d485b82..89d279c 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
@@ -32,6 +32,9 @@
import android.tools.flicker.config.desktopmode.Components
import android.tools.flicker.extractors.ITransitionMatcher
import android.tools.flicker.extractors.ShellTransitionScenarioExtractor
+import android.tools.flicker.extractors.TaggedCujTransitionMatcher
+import android.tools.flicker.extractors.TaggedScenarioExtractorBuilder
+import android.tools.traces.events.CujType
import android.tools.traces.wm.Transition
import android.tools.traces.wm.TransitionType
@@ -121,24 +124,17 @@
FlickerConfigEntry(
scenarioId = ScenarioId("CORNER_RESIZE"),
extractor =
- ShellTransitionScenarioExtractor(
- transitionMatcher =
- object : ITransitionMatcher {
- override fun findAll(
- transitions: Collection<Transition>
- ): Collection<Transition> {
- return transitions.filter {
- it.type == TransitionType.CHANGE
- }
- }
- }
- ),
+ TaggedScenarioExtractorBuilder()
+ .setTargetTag(CujType.CUJ_DESKTOP_MODE_RESIZE_WINDOW)
+ .setTransitionMatcher(
+ TaggedCujTransitionMatcher(associatedTransitionRequired = false)
+ ).build(),
assertions =
- listOf(
- AppWindowIsVisibleAlways(Components.DESKTOP_MODE_APP),
- AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
- AppWindowRemainInsideDisplayBounds(Components.DESKTOP_MODE_APP),
- ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
+ listOf(
+ AppWindowIsVisibleAlways(Components.DESKTOP_MODE_APP),
+ AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
+ AppWindowRemainInsideDisplayBounds(Components.DESKTOP_MODE_APP),
+ ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
index c671fbe..b5a6d83 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
@@ -48,6 +48,8 @@
fun setup() {
tapl.setEnableRotation(true)
tapl.setExpectedRotation(rotation.value)
+ // TODO: b/349075982 - Remove once launcher rotation and checks are stable.
+ tapl.setExpectedRotationCheckEnabled(false)
SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp, rotation)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index f9b4108..8303317 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -687,6 +687,25 @@
verify(mRecentTasksController).onTaskRunningInfoChanged(task2);
}
+ @Test
+ public void testTaskVanishedCallback() {
+ RunningTaskInfo task1 = createTaskInfo(/* taskId= */ 1, WINDOWING_MODE_FULLSCREEN);
+ mOrganizer.onTaskAppeared(task1, /* leash= */ null);
+
+ RunningTaskInfo[] vanishedTasks = new RunningTaskInfo[1];
+ ShellTaskOrganizer.TaskVanishedListener listener =
+ new ShellTaskOrganizer.TaskVanishedListener() {
+ @Override
+ public void onTaskVanished(RunningTaskInfo taskInfo) {
+ vanishedTasks[0] = taskInfo;
+ }
+ };
+ mOrganizer.addTaskVanishedListener(listener);
+ mOrganizer.onTaskVanished(task1);
+
+ assertEquals(vanishedTasks[0], task1);
+ }
+
private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) {
RunningTaskInfo taskInfo = new RunningTaskInfo();
taskInfo.taskId = taskId;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
index 51a20ee..a2df22c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
@@ -26,7 +26,7 @@
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import org.junit.After;
import org.junit.Before;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
index 731f75bf..55b6bd2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
@@ -21,10 +21,12 @@
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.calculateParentBounds;
+import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.shouldUseJumpCutForAnimation;
import static com.android.wm.shell.transition.Transitions.TRANSIT_TASK_FRAGMENT_DRAG_RESIZE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
@@ -40,6 +42,8 @@
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
import android.window.TransitionInfo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -281,6 +285,18 @@
actualParentBounds);
}
+ @Test
+ public void testShouldUseJumpCutForAnimation() {
+ final Animation noopAnimation = new AlphaAnimation(0f, 1f);
+ assertTrue("Animation without duration should use jump cut.",
+ shouldUseJumpCutForAnimation(noopAnimation));
+
+ final Animation alphaAnimation = new AlphaAnimation(0f, 1f);
+ alphaAnimation.setDuration(100);
+ assertFalse("Animation with duration should not use jump cut.",
+ shouldUseJumpCutForAnimation(alphaAnimation));
+ }
+
@NonNull
private static TransitionInfo.Change prepareChangeForParentBoundsCalculationTest(
@NonNull Point endRelOffset, @NonNull Rect endAbsBounds, @NonNull Point endParentSize) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 14fa0f1..a3b0dc5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -18,6 +18,7 @@
import android.app.ActivityManager.RecentTaskInfo
import android.app.ActivityManager.RunningTaskInfo
+import android.app.KeyguardManager
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
@@ -149,6 +150,7 @@
@Mock lateinit var syncQueue: SyncTransactionQueue
@Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
@Mock lateinit var transitions: Transitions
+ @Mock lateinit var keyguardManager: KeyguardManager
@Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler
@Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler
@Mock
@@ -191,7 +193,7 @@
.strictness(Strictness.LENIENT)
.spyStatic(DesktopModeStatus::class.java)
.startMocking()
- whenever(DesktopModeStatus.isEnabled()).thenReturn(true)
+ whenever(DesktopModeStatus.isDesktopModeFlagEnabled()).thenReturn(true)
doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
shellInit = spy(ShellInit(testExecutor))
@@ -233,6 +235,7 @@
rootTaskDisplayAreaOrganizer,
dragAndDropController,
transitions,
+ keyguardManager,
enterDesktopTransitionHandler,
exitDesktopTransitionHandler,
toggleResizeDesktopTaskTransitionHandler,
@@ -261,7 +264,7 @@
@Test
fun instantiate_flagOff_doNotAddInitCallback() {
- whenever(DesktopModeStatus.isEnabled()).thenReturn(false)
+ whenever(DesktopModeStatus.isDesktopModeFlagEnabled()).thenReturn(false)
clearInvocations(shellInit)
createController()
@@ -1084,13 +1087,17 @@
fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() {
assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ val homeTask = setUpHomeTask()
val freeformTask = setUpFreeformTask()
markTaskVisible(freeformTask)
val fullscreenTask = createFullscreenTask()
- val result = controller.handleRequest(Binder(), createTransition(fullscreenTask))
- assertThat(result?.changes?.get(fullscreenTask.token.asBinder())?.windowingMode)
+ val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+ assertThat(wct?.changes?.get(fullscreenTask.token.asBinder())?.windowingMode)
.isEqualTo(WINDOWING_MODE_FREEFORM)
+
+ assertThat(wct!!.hierarchyOps.size).isEqualTo(2)
+ wct.assertReorderAt(1, homeTask, toTop = false)
}
@Test
@@ -1301,6 +1308,17 @@
}
@Test
+ fun handleRequest_freeformTask_keyguardLocked_returnNull() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
+ val freeformTask = createFreeformTask(displayId = DEFAULT_DISPLAY)
+
+ val result = controller.handleRequest(Binder(), createTransition(freeformTask))
+
+ assertNull(result, "Should NOT handle request")
+ }
+
+ @Test
fun handleRequest_notOpenOrToFrontTransition_returnNull() {
assumeTrue(ENABLE_SHELL_TRANSITIONS)
@@ -1902,6 +1920,26 @@
}
@Test
+ fun toggleBounds_togglesToCalculatedBoundsForNonResizable() {
+ val bounds = Rect(0, 0, 200, 100)
+ val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds).apply {
+ topActivityInfo = ActivityInfo().apply {
+ screenOrientation = SCREEN_ORIENTATION_LANDSCAPE
+ configuration.windowConfiguration.appBounds = bounds
+ }
+ isResizeable = false
+ }
+
+ // Bounds should be 1000 x 500, vertically centered in the 1000 x 1000 stable bounds
+ val expectedBounds = Rect(STABLE_BOUNDS.left, 250, STABLE_BOUNDS.right, 750)
+
+ controller.toggleDesktopTaskSize(task)
+ // Assert bounds set to stable bounds
+ val wct = getLatestToggleResizeDesktopTaskWct()
+ assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
+ }
+
+ @Test
fun toggleBounds_lastBoundsBeforeMaximizeSaved() {
val bounds = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
@@ -1928,6 +1966,46 @@
}
@Test
+ fun toggleBounds_togglesFromStableBoundsToLastBoundsBeforeMaximize_nonResizeableEqualWidth() {
+ val boundsBeforeMaximize = Rect(0, 0, 100, 100)
+ val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize).apply {
+ isResizeable = false
+ }
+
+ // Maximize
+ controller.toggleDesktopTaskSize(task)
+ task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS.left,
+ boundsBeforeMaximize.top, STABLE_BOUNDS.right, boundsBeforeMaximize.bottom)
+
+ // Restore
+ controller.toggleDesktopTaskSize(task)
+
+ // Assert bounds set to last bounds before maximize
+ val wct = getLatestToggleResizeDesktopTaskWct()
+ assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
+ }
+
+ @Test
+ fun toggleBounds_togglesFromStableBoundsToLastBoundsBeforeMaximize_nonResizeableEqualHeight() {
+ val boundsBeforeMaximize = Rect(0, 0, 100, 100)
+ val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize).apply {
+ isResizeable = false
+ }
+
+ // Maximize
+ controller.toggleDesktopTaskSize(task)
+ task.configuration.windowConfiguration.bounds.set(boundsBeforeMaximize.left,
+ STABLE_BOUNDS.top, boundsBeforeMaximize.right, STABLE_BOUNDS.bottom)
+
+ // Restore
+ controller.toggleDesktopTaskSize(task)
+
+ // Assert bounds set to last bounds before maximize
+ val wct = getLatestToggleResizeDesktopTaskWct()
+ assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
+ }
+
+ @Test
fun toggleBounds_removesLastBoundsBeforeMaximizeAfterRestoringBounds() {
val boundsBeforeMaximize = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java
index a64ebd3..8401264 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java
@@ -76,6 +76,8 @@
@Mock
private ShellCommandHandler mShellCommandHandler;
@Mock
+ private ShellTaskOrganizer mShellTaskOrganizer;
+ @Mock
private DisplayController mDisplayController;
@Mock
private UiEventLogger mUiEventLogger;
@@ -96,8 +98,8 @@
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
mController = new DragAndDropController(mContext, mShellInit, mShellController,
- mShellCommandHandler, mDisplayController, mUiEventLogger, mIconProvider,
- mGlobalDragListener, mTransitions, mMainExecutor);
+ mShellCommandHandler, mShellTaskOrganizer, mDisplayController, mUiEventLogger,
+ mIconProvider, mGlobalDragListener, mTransitions, mMainExecutor);
mController.onInit();
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
index 6e72e8d..582fb91 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -65,8 +65,6 @@
import android.graphics.Insets;
import android.os.RemoteException;
import android.view.DisplayInfo;
-import android.view.DragEvent;
-import android.view.View;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -76,7 +74,6 @@
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.draganddrop.DragAndDropPolicy.Target;
import com.android.wm.shell.splitscreen.SplitScreenController;
-import com.android.wm.shell.startingsurface.TaskSnapshotWindow;
import org.junit.After;
import org.junit.Before;
@@ -106,6 +103,8 @@
// Both the split-screen and start interface.
@Mock
private SplitScreenController mSplitScreenStarter;
+ @Mock
+ private DragAndDropPolicy.Starter mFullscreenStarter;
@Mock
private InstanceId mLoggerSessionId;
@@ -151,7 +150,7 @@
mPortraitDisplayLayout = new DisplayLayout(info2, res, false, false);
mInsets = Insets.of(0, 0, 0, 0);
- mPolicy = spy(new DragAndDropPolicy(mContext, mSplitScreenStarter, mSplitScreenStarter));
+ mPolicy = spy(new DragAndDropPolicy(mContext, mSplitScreenStarter, mFullscreenStarter));
mActivityClipData = createAppClipData(MIMETYPE_APPLICATION_ACTIVITY);
mLaunchableIntentPendingIntent = mock(PendingIntent.class);
when(mLaunchableIntentPendingIntent.getCreatorUserHandle())
@@ -285,13 +284,13 @@
setRunningTask(mHomeTask);
DragSession dragSession = new DragSession(mActivityTaskManager,
mLandscapeDisplayLayout, data, 0 /* dragFlags */);
- dragSession.update();
+ dragSession.initialize();
mPolicy.start(dragSession, mLoggerSessionId);
ArrayList<Target> targets = assertExactTargetTypes(
mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN));
- verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
+ verify(mFullscreenStarter).startIntent(any(), anyInt(), any(),
eq(SPLIT_POSITION_UNDEFINED), any());
}
@@ -300,7 +299,7 @@
setRunningTask(mFullscreenAppTask);
DragSession dragSession = new DragSession(mActivityTaskManager,
mLandscapeDisplayLayout, data, 0 /* dragFlags */);
- dragSession.update();
+ dragSession.initialize();
mPolicy.start(dragSession, mLoggerSessionId);
ArrayList<Target> targets = assertExactTargetTypes(
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
@@ -320,7 +319,7 @@
setRunningTask(mFullscreenAppTask);
DragSession dragSession = new DragSession(mActivityTaskManager,
mPortraitDisplayLayout, data, 0 /* dragFlags */);
- dragSession.update();
+ dragSession.initialize();
mPolicy.start(dragSession, mLoggerSessionId);
ArrayList<Target> targets = assertExactTargetTypes(
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
@@ -340,7 +339,7 @@
setRunningTask(mFullscreenAppTask);
DragSession dragSession = new DragSession(mActivityTaskManager,
mLandscapeDisplayLayout, mActivityClipData, 0 /* dragFlags */);
- dragSession.update();
+ dragSession.initialize();
mPolicy.start(dragSession, mLoggerSessionId);
ArrayList<Target> targets = mPolicy.getTargets(mInsets);
for (Target t : targets) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index d38fc6c..75d2145 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -34,7 +34,6 @@
import static java.lang.Integer.MAX_VALUE;
-import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@@ -183,7 +182,7 @@
@Test
public void instantiatePipController_registersPipTransitionCallback() {
- verify(mMockPipTransitionController).registerPipTransitionCallback(any());
+ verify(mMockPipTransitionController).registerPipTransitionCallback(any(), any());
}
@Test
@@ -235,27 +234,6 @@
}
@Test
- public void onActivityHidden_isLastPipComponentName_clearLastPipComponent() {
- final ComponentName component1 = new ComponentName(mContext, "component1");
- when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1);
-
- mPipController.mPinnedTaskListener.onActivityHidden(component1);
-
- verify(mMockPipBoundsState).setLastPipComponentName(null);
- }
-
- @Test
- public void onActivityHidden_isNotLastPipComponentName_lastPipComponentNotCleared() {
- final ComponentName component1 = new ComponentName(mContext, "component1");
- final ComponentName component2 = new ComponentName(mContext, "component2");
- when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1);
-
- mPipController.mPinnedTaskListener.onActivityHidden(component2);
-
- verify(mMockPipBoundsState, never()).setLastPipComponentName(null);
- }
-
- @Test
public void saveReentryState_savesPipBoundsState() {
final Rect bounds = new Rect(0, 0, 10, 10);
when(mMockPipBoundsAlgorithm.getSnapFraction(bounds)).thenReturn(1.0f);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
index ace09a8..66f8c0b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
@@ -114,8 +114,8 @@
final PipBoundsAlgorithm pipBoundsAlgorithm = new PipBoundsAlgorithm(mContext,
mPipBoundsState, pipSnapAlgorithm, pipKeepClearAlgorithm, mPipDisplayLayoutState,
mSizeSpecSource);
- final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mPipBoundsState,
- mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm,
+ final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mMainExecutor,
+ mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm,
mMockPipTransitionController, mFloatingContentCoordinator,
Optional.empty() /* pipPerfHintControllerOptional */);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index 92762fa..6d18e36 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -116,8 +116,8 @@
mPipSnapAlgorithm = new PipSnapAlgorithm();
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState, mPipSnapAlgorithm,
new PipKeepClearAlgorithmInterface() {}, mPipDisplayLayoutState, mSizeSpecSource);
- PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mPipBoundsState,
- mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm,
+ PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mMainExecutor,
+ mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm,
mMockPipTransitionController, mFloatingContentCoordinator,
Optional.empty() /* pipPerfHintControllerOptional */);
mPipTouchHandler = new PipTouchHandler(mContext, mShellInit, mPhonePipMenuController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
index f959970..0e5efa6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
@@ -48,7 +48,6 @@
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
-
/**
* Test class for {@link TaskStackTransitionObserver}
*
@@ -168,6 +167,80 @@
.isEqualTo(freeformOpenChange.taskInfo?.windowingMode)
}
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+ fun transitionMerged_withChange_onlyOpenChangeIsNotified() {
+ val listener = TestListener()
+ val executor = TestShellExecutor()
+ transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
+
+ // Create open transition
+ val change =
+ createChange(
+ WindowManager.TRANSIT_OPEN,
+ createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+ )
+ val transitionInfo =
+ TransitionInfoBuilder(WindowManager.TRANSIT_OPEN, 0).addChange(change).build()
+
+ // create change transition to be merged to above transition
+ val mergedChange =
+ createChange(
+ WindowManager.TRANSIT_CHANGE,
+ createTaskInfo(2, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+ )
+ val mergedTransitionInfo =
+ TransitionInfoBuilder(WindowManager.TRANSIT_CHANGE, 0).addChange(mergedChange).build()
+ val mergedTransition = Mockito.mock(IBinder::class.java)
+
+ callOnTransitionReady(transitionInfo)
+ callOnTransitionReady(mergedTransitionInfo, mergedTransition)
+ callOnTransitionMerged(mergedTransition)
+ callOnTransitionFinished()
+ executor.flushAll()
+
+ assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(change.taskInfo?.taskId)
+ assertThat(listener.taskInfoToBeNotified.windowingMode)
+ .isEqualTo(change.taskInfo?.windowingMode)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+ fun transitionMerged_withOpen_lastOpenChangeIsNotified() {
+ val listener = TestListener()
+ val executor = TestShellExecutor()
+ transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
+
+ // Create open transition
+ val change =
+ createChange(
+ WindowManager.TRANSIT_OPEN,
+ createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+ )
+ val transitionInfo =
+ TransitionInfoBuilder(WindowManager.TRANSIT_OPEN, 0).addChange(change).build()
+
+ // create change transition to be merged to above transition
+ val mergedChange =
+ createChange(
+ WindowManager.TRANSIT_OPEN,
+ createTaskInfo(2, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+ )
+ val mergedTransitionInfo =
+ TransitionInfoBuilder(WindowManager.TRANSIT_OPEN, 0).addChange(mergedChange).build()
+ val mergedTransition = Mockito.mock(IBinder::class.java)
+
+ callOnTransitionReady(transitionInfo)
+ callOnTransitionReady(mergedTransitionInfo, mergedTransition)
+ callOnTransitionMerged(mergedTransition)
+ callOnTransitionFinished()
+ executor.flushAll()
+
+ assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(mergedChange.taskInfo?.taskId)
+ assertThat(listener.taskInfoToBeNotified.windowingMode)
+ .isEqualTo(mergedChange.taskInfo?.windowingMode)
+ }
+
class TestListener : TaskStackTransitionObserver.TaskStackTransitionObserverListener {
var taskInfoToBeNotified = ActivityManager.RunningTaskInfo()
@@ -179,11 +252,14 @@
}
/** Simulate calling the onTransitionReady() method */
- private fun callOnTransitionReady(transitionInfo: TransitionInfo) {
+ private fun callOnTransitionReady(
+ transitionInfo: TransitionInfo,
+ transition: IBinder = mockTransitionBinder
+ ) {
val startT = Mockito.mock(SurfaceControl.Transaction::class.java)
val finishT = Mockito.mock(SurfaceControl.Transaction::class.java)
- transitionObserver.onTransitionReady(mockTransitionBinder, transitionInfo, startT, finishT)
+ transitionObserver.onTransitionReady(transition, transitionInfo, startT, finishT)
}
/** Simulate calling the onTransitionFinished() method */
@@ -191,6 +267,11 @@
transitionObserver.onTransitionFinished(mockTransitionBinder, false)
}
+ /** Simulate calling the onTransitionMerged() method */
+ private fun callOnTransitionMerged(merged: IBinder, playing: IBinder = mockTransitionBinder) {
+ transitionObserver.onTransitionMerged(merged, playing)
+ }
+
companion object {
fun createTaskInfo(taskId: Int, windowingMode: Int): ActivityManager.RunningTaskInfo {
val taskInfo = ActivityManager.RunningTaskInfo()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ChangeBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ChangeBuilder.java
new file mode 100644
index 0000000..b54c3bf
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ChangeBuilder.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.transition;
+
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.window.TransitionInfo;
+
+public class ChangeBuilder {
+ final TransitionInfo.Change mChange;
+
+ ChangeBuilder(@WindowManager.TransitionType int mode) {
+ mChange = new TransitionInfo.Change(null /* token */, createMockSurface(true));
+ mChange.setMode(mode);
+ }
+
+ ChangeBuilder setFlags(@TransitionInfo.ChangeFlags int flags) {
+ mChange.setFlags(flags);
+ return this;
+ }
+
+ ChangeBuilder setTask(RunningTaskInfo taskInfo) {
+ mChange.setTaskInfo(taskInfo);
+ return this;
+ }
+
+ ChangeBuilder setRotate(int anim) {
+ return setRotate(Surface.ROTATION_90, anim);
+ }
+
+ ChangeBuilder setRotate() {
+ return setRotate(ROTATION_ANIMATION_UNSPECIFIED);
+ }
+
+ ChangeBuilder setRotate(@Surface.Rotation int target, int anim) {
+ mChange.setRotation(Surface.ROTATION_0, target);
+ mChange.setRotationAnimation(anim);
+ return this;
+ }
+
+ TransitionInfo.Change build() {
+ return mChange;
+ }
+
+ private static SurfaceControl createMockSurface(boolean valid) {
+ SurfaceControl sc = mock(SurfaceControl.class);
+ doReturn(valid).when(sc).isValid();
+ return sc;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
new file mode 100644
index 0000000..754a173
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.transition;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_SLEEP;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.window.TransitionInfo.FLAG_SYNC;
+import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import android.window.WindowContainerToken;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestShellExecutor;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.sysui.ShellInit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the default animation handler that is used if no other special-purpose handler picks
+ * up an animation request.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:DefaultTransitionHandlerTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DefaultTransitionHandlerTest extends ShellTestCase {
+
+ private final Context mContext =
+ InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ private final DisplayController mDisplayController = mock(DisplayController.class);
+ private final TransactionPool mTransactionPool = new MockTransactionPool();
+ private final TestShellExecutor mMainExecutor = new TestShellExecutor();
+ private final TestShellExecutor mAnimExecutor = new TestShellExecutor();
+ private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+
+ private ShellInit mShellInit;
+ private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+ private DefaultTransitionHandler mTransitionHandler;
+
+ @Before
+ public void setUp() {
+ mShellInit = new ShellInit(mMainExecutor);
+ mRootTaskDisplayAreaOrganizer = new RootTaskDisplayAreaOrganizer(
+ mMainExecutor,
+ mContext,
+ mShellInit);
+ mTransitionHandler = new DefaultTransitionHandler(
+ mContext, mShellInit, mDisplayController,
+ mTransactionPool, mMainExecutor, mMainHandler, mAnimExecutor,
+ mRootTaskDisplayAreaOrganizer);
+ mShellInit.init();
+ }
+
+ @After
+ public void tearDown() {
+ flushHandlers();
+ }
+
+ private void flushHandlers() {
+ mMainHandler.runWithScissors(() -> {
+ mAnimExecutor.flushAll();
+ mMainExecutor.flushAll();
+ }, 1000L);
+ }
+
+ @Test
+ public void testAnimationBackgroundCreatedForTaskTransition() {
+ final TransitionInfo.Change openTask = new ChangeBuilder(TRANSIT_OPEN)
+ .setTask(createTaskInfo(1))
+ .build();
+ final TransitionInfo.Change closeTask = new ChangeBuilder(TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(2))
+ .build();
+
+ final IBinder token = new Binder();
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(openTask)
+ .addChange(closeTask)
+ .build();
+ final SurfaceControl.Transaction startT = MockTransactionPool.create();
+ final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+ mTransitionHandler.startAnimation(token, info, startT, finishT,
+ mock(Transitions.TransitionFinishCallback.class));
+
+ mergeSync(mTransitionHandler, token);
+ flushHandlers();
+
+ verify(startT).setColor(any(), any());
+ }
+
+ @Test
+ public void testNoAnimationBackgroundForTranslucentTasks() {
+ final TransitionInfo.Change openTask = new ChangeBuilder(TRANSIT_OPEN)
+ .setTask(createTaskInfo(1))
+ .setFlags(FLAG_TRANSLUCENT)
+ .build();
+ final TransitionInfo.Change closeTask = new ChangeBuilder(TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(2))
+ .setFlags(FLAG_TRANSLUCENT)
+ .build();
+
+ final IBinder token = new Binder();
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(openTask)
+ .addChange(closeTask)
+ .build();
+ final SurfaceControl.Transaction startT = MockTransactionPool.create();
+ final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+ mTransitionHandler.startAnimation(token, info, startT, finishT,
+ mock(Transitions.TransitionFinishCallback.class));
+
+ mergeSync(mTransitionHandler, token);
+ flushHandlers();
+
+ verify(startT, never()).setColor(any(), any());
+ }
+
+ @Test
+ public void testNoAnimationBackgroundForWallpapers() {
+ final TransitionInfo.Change openWallpaper = new ChangeBuilder(TRANSIT_OPEN)
+ .setFlags(TransitionInfo.FLAG_IS_WALLPAPER)
+ .build();
+ final TransitionInfo.Change closeWallpaper = new ChangeBuilder(TRANSIT_TO_BACK)
+ .setFlags(TransitionInfo.FLAG_IS_WALLPAPER)
+ .build();
+
+ final IBinder token = new Binder();
+ final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(openWallpaper)
+ .addChange(closeWallpaper)
+ .build();
+ final SurfaceControl.Transaction startT = MockTransactionPool.create();
+ final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+ mTransitionHandler.startAnimation(token, info, startT, finishT,
+ mock(Transitions.TransitionFinishCallback.class));
+
+ mergeSync(mTransitionHandler, token);
+ flushHandlers();
+
+ verify(startT, never()).setColor(any(), any());
+ }
+
+ private static void mergeSync(Transitions.TransitionHandler handler, IBinder token) {
+ handler.mergeAnimation(
+ new Binder(),
+ new TransitionInfoBuilder(TRANSIT_SLEEP, FLAG_SYNC).build(),
+ MockTransactionPool.create(),
+ token,
+ mock(Transitions.TransitionFinishCallback.class));
+ }
+
+ private static RunningTaskInfo createTaskInfo(int taskId) {
+ RunningTaskInfo taskInfo = new RunningTaskInfo();
+ taskInfo.taskId = taskId;
+ taskInfo.topActivityType = ACTIVITY_TYPE_STANDARD;
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ taskInfo.configuration.windowConfiguration.setActivityType(taskInfo.topActivityType);
+ taskInfo.token = mock(WindowContainerToken.class);
+ return taskInfo;
+ }
+}
+
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/MockTransactionPool.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/MockTransactionPool.java
new file mode 100644
index 0000000..574a87a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/MockTransactionPool.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.transition;
+
+import static org.mockito.Mockito.RETURNS_SELF;
+import static org.mockito.Mockito.mock;
+
+import android.view.SurfaceControl;
+
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.util.StubTransaction;
+
+public class MockTransactionPool extends TransactionPool {
+
+ public static SurfaceControl.Transaction create() {
+ return mock(StubTransaction.class, RETURNS_SELF);
+ }
+
+ @Override
+ public SurfaceControl.Transaction acquire() {
+ return create();
+ }
+
+ @Override
+ public void release(SurfaceControl.Transaction t) {
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index 69a61ea..8331d59 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -79,7 +79,6 @@
import android.view.IRecentsAnimationRunner;
import android.view.Surface;
import android.view.SurfaceControl;
-import android.view.WindowManager;
import android.window.IRemoteTransition;
import android.window.IRemoteTransitionFinishedCallback;
import android.window.IWindowContainerToken;
@@ -1615,43 +1614,6 @@
eq(R.styleable.WindowAnimation_activityCloseEnterAnimation), anyBoolean());
}
- class ChangeBuilder {
- final TransitionInfo.Change mChange;
-
- ChangeBuilder(@WindowManager.TransitionType int mode) {
- mChange = new TransitionInfo.Change(null /* token */, createMockSurface(true));
- mChange.setMode(mode);
- }
-
- ChangeBuilder setFlags(@TransitionInfo.ChangeFlags int flags) {
- mChange.setFlags(flags);
- return this;
- }
-
- ChangeBuilder setTask(RunningTaskInfo taskInfo) {
- mChange.setTaskInfo(taskInfo);
- return this;
- }
-
- ChangeBuilder setRotate(int anim) {
- return setRotate(Surface.ROTATION_90, anim);
- }
-
- ChangeBuilder setRotate() {
- return setRotate(ROTATION_ANIMATION_UNSPECIFIED);
- }
-
- ChangeBuilder setRotate(@Surface.Rotation int target, int anim) {
- mChange.setRotation(Surface.ROTATION_0, target);
- mChange.setRotationAnimation(anim);
- return this;
- }
-
- TransitionInfo.Change build() {
- return mChange;
- }
- }
-
class TestTransitionHandler implements Transitions.TransitionHandler {
ArrayList<Pair<IBinder, Transitions.TransitionFinishCallback>> mFinishes =
new ArrayList<>();
@@ -1740,12 +1702,6 @@
.addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build();
}
- private static SurfaceControl createMockSurface(boolean valid) {
- SurfaceControl sc = mock(SurfaceControl.class);
- doReturn(valid).when(sc).isValid();
- return sc;
- }
-
private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode, int activityType) {
RunningTaskInfo taskInfo = new RunningTaskInfo();
taskInfo.taskId = taskId;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index ca1e3f1..0ec6713 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -55,6 +55,7 @@
import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
@@ -67,6 +68,7 @@
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopTasksController
+import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
import com.android.wm.shell.shared.DesktopModeStatus
import com.android.wm.shell.sysui.KeyguardChangeListener
@@ -75,6 +77,7 @@
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener
import java.util.Optional
import java.util.function.Supplier
import org.junit.Assert.assertEquals
@@ -82,6 +85,7 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.anyInt
@@ -131,6 +135,7 @@
@Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
@Mock private lateinit var mockShellCommandHandler: ShellCommandHandler
@Mock private lateinit var mockWindowManager: IWindowManager
+ @Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
private val transactionFactory = Supplier<SurfaceControl.Transaction> {
SurfaceControl.Transaction()
@@ -164,7 +169,7 @@
mockInputMonitorFactory,
transactionFactory,
mockRootTaskDisplayAreaOrganizer,
- windowDecorByTaskIdSpy
+ windowDecorByTaskIdSpy, mockInteractionJankMonitor
)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -518,6 +523,99 @@
}
}
+ @Test
+ fun testOnDecorMaximizedOrRestored_togglesTaskSize() {
+ val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+ onTaskOpening(decor.mTaskInfo)
+ val maxOrRestoreListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+ .let { captor ->
+ verify(decor).setOnMaximizeOrRestoreClickListener(captor.capture())
+ return@let captor.value
+ }
+
+ maxOrRestoreListener.onClick(decor.mTaskInfo.taskId, "test")
+
+ verify(mockDesktopTasksController).toggleDesktopTaskSize(decor.mTaskInfo)
+ }
+
+ @Test
+ fun testOnDecorMaximizedOrRestored_closesMenus() {
+ val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+ onTaskOpening(decor.mTaskInfo)
+ val maxOrRestoreListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+ .let { captor ->
+ verify(decor).setOnMaximizeOrRestoreClickListener(captor.capture())
+ return@let captor.value
+ }
+
+ maxOrRestoreListener.onClick(decor.mTaskInfo.taskId, "test")
+
+ verify(decor).closeHandleMenu()
+ verify(decor).closeMaximizeMenu()
+ }
+
+ @Test
+ fun testOnDecorSnappedLeft_snapResizes() {
+ val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+ onTaskOpening(decor.mTaskInfo)
+ val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+ .let { captor ->
+ verify(decor).setOnLeftSnapClickListener(captor.capture())
+ return@let captor.value
+ }
+
+ snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+ verify(mockDesktopTasksController).snapToHalfScreen(decor.mTaskInfo, SnapPosition.LEFT)
+ }
+
+ @Test
+ fun testOnDecorSnappedLeft_closeMenus() {
+ val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+ onTaskOpening(decor.mTaskInfo)
+ val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+ .let { captor ->
+ verify(decor).setOnLeftSnapClickListener(captor.capture())
+ return@let captor.value
+ }
+
+ snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+ verify(decor).closeHandleMenu()
+ verify(decor).closeMaximizeMenu()
+ }
+
+ @Test
+ fun testOnDecorSnappedRight_snapResizes() {
+ val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+ onTaskOpening(decor.mTaskInfo)
+ val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+ .let { captor ->
+ verify(decor).setOnRightSnapClickListener(captor.capture())
+ return@let captor.value
+ }
+
+ snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+ verify(mockDesktopTasksController).snapToHalfScreen(decor.mTaskInfo, SnapPosition.RIGHT)
+ }
+
+ @Test
+ fun testOnDecorSnappedRight_closeMenus() {
+ val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+ onTaskOpening(decor.mTaskInfo)
+ val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+ .let { captor ->
+ verify(decor).setOnRightSnapClickListener(captor.capture())
+ return@let captor.value
+ }
+
+ snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+ verify(decor).closeHandleMenu()
+ verify(decor).closeMaximizeMenu()
+ }
+
private fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
desktopModeWindowDecorViewModel.onTaskOpening(
task,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 46c1589..8165e59 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -24,9 +24,14 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction;
+import static com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.CLOSE_MAXIMIZE_MENU_DELAY_MS;
import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -38,11 +43,13 @@
import android.app.ActivityManager;
import android.content.ComponentName;
+import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.PointF;
import android.os.Handler;
import android.os.SystemProperties;
import android.platform.test.annotations.DisableFlags;
@@ -62,6 +69,7 @@
import android.view.WindowManager;
import android.window.WindowContainerTransaction;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
@@ -76,6 +84,10 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.DesktopModeStatus;
import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams;
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener;
+
+import kotlin.Unit;
+import kotlin.jvm.functions.Function1;
import org.junit.After;
import org.junit.Before;
@@ -84,6 +96,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.quality.Strictness;
@@ -112,8 +125,6 @@
@Mock
private ShellTaskOrganizer mMockShellTaskOrganizer;
@Mock
- private Handler mMockHandler;
- @Mock
private Choreographer mMockChoreographer;
@Mock
private SyncTransactionQueue mMockSyncQueue;
@@ -131,13 +142,18 @@
private WindowDecoration.SurfaceControlViewHostFactory mMockSurfaceControlViewHostFactory;
@Mock
private TypedArray mMockRoundedCornersRadiusArray;
-
@Mock
private TestTouchEventListener mMockTouchEventListener;
@Mock
private DesktopModeWindowDecoration.ExclusionRegionListener mMockExclusionRegionListener;
@Mock
private PackageManager mMockPackageManager;
+ @Mock
+ private Handler mMockHandler;
+ @Captor
+ private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
+ @Captor
+ private ArgumentCaptor<Runnable> mCloseMaxMenuRunnable;
private final InsetsState mInsetsState = new InsetsState();
private SurfaceControl.Transaction mMockTransaction;
@@ -154,7 +170,7 @@
}
@Before
- public void setUp() {
+ public void setUp() throws PackageManager.NameNotFoundException {
mMockitoSession = mockitoSession()
.strictness(Strictness.LENIENT)
.spyStatic(DesktopModeStatus.class)
@@ -170,6 +186,9 @@
mTestableContext.ensureTestableResources();
mContext.setMockPackageManager(mMockPackageManager);
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("applicationLabel");
+ final ActivityInfo activityInfo = new ActivityInfo();
+ activityInfo.applicationInfo = new ApplicationInfo();
+ when(mMockPackageManager.getActivityInfo(any(), anyInt())).thenReturn(activityInfo);
final Display defaultDisplay = mock(Display.class);
doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
@@ -459,6 +478,92 @@
verify(mMockHandler).removeCallbacks(runnableArgument.getValue());
}
+ @Test
+ public void createMaximizeMenu_showsMenu() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final MaximizeMenu menu = mock(MaximizeMenu.class);
+ final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+ new FakeMaximizeMenuFactory(menu));
+ assertFalse(decoration.isMaximizeMenuActive());
+
+ createMaximizeMenu(decoration, menu);
+
+ assertTrue(decoration.isMaximizeMenuActive());
+ }
+
+ @Test
+ public void maximizeMenu_unHoversMenu_schedulesCloseMenu() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final MaximizeMenu menu = mock(MaximizeMenu.class);
+ final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+ new FakeMaximizeMenuFactory(menu));
+ decoration.setAppHeaderMaximizeButtonHovered(false);
+ createMaximizeMenu(decoration, menu);
+
+ mOnMaxMenuHoverChangeListener.getValue().invoke(false);
+
+ verify(mMockHandler)
+ .postDelayed(mCloseMaxMenuRunnable.capture(), eq(CLOSE_MAXIMIZE_MENU_DELAY_MS));
+
+ mCloseMaxMenuRunnable.getValue().run();
+ verify(menu).close();
+ assertFalse(decoration.isMaximizeMenuActive());
+ }
+
+ @Test
+ public void maximizeMenu_unHoversButton_schedulesCloseMenu() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final MaximizeMenu menu = mock(MaximizeMenu.class);
+ final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+ new FakeMaximizeMenuFactory(menu));
+ decoration.setAppHeaderMaximizeButtonHovered(true);
+ createMaximizeMenu(decoration, menu);
+
+ decoration.setAppHeaderMaximizeButtonHovered(false);
+
+ verify(mMockHandler)
+ .postDelayed(mCloseMaxMenuRunnable.capture(), eq(CLOSE_MAXIMIZE_MENU_DELAY_MS));
+
+ mCloseMaxMenuRunnable.getValue().run();
+ verify(menu).close();
+ assertFalse(decoration.isMaximizeMenuActive());
+ }
+
+ @Test
+ public void maximizeMenu_hoversMenu_cancelsCloseMenu() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final MaximizeMenu menu = mock(MaximizeMenu.class);
+ final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+ new FakeMaximizeMenuFactory(menu));
+ createMaximizeMenu(decoration, menu);
+
+ mOnMaxMenuHoverChangeListener.getValue().invoke(true);
+
+ verify(mMockHandler).removeCallbacks(any());
+ }
+
+ @Test
+ public void maximizeMenu_hoversButton_cancelsCloseMenu() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+ final MaximizeMenu menu = mock(MaximizeMenu.class);
+ final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+ new FakeMaximizeMenuFactory(menu));
+ createMaximizeMenu(decoration, menu);
+
+ decoration.setAppHeaderMaximizeButtonHovered(true);
+
+ verify(mMockHandler).removeCallbacks(any());
+ }
+
+ private void createMaximizeMenu(DesktopModeWindowDecoration decoration, MaximizeMenu menu) {
+ final OnTaskActionClickListener l = (taskId, tag) -> {};
+ decoration.setOnMaximizeOrRestoreClickListener(l);
+ decoration.setOnLeftSnapClickListener(l);
+ decoration.setOnRightSnapClickListener(l);
+ decoration.createMaximizeMenu();
+ verify(menu).show(any(), any(), any(), mOnMaxMenuHoverChangeListener.capture());
+ }
+
private void fillRoundedCornersResources(int fillValue) {
when(mMockRoundedCornersRadiusArray.getDimensionPixelSize(anyInt(), anyInt()))
.thenReturn(fillValue);
@@ -479,12 +584,19 @@
private DesktopModeWindowDecoration createWindowDecoration(
ActivityManager.RunningTaskInfo taskInfo) {
- DesktopModeWindowDecoration windowDecor = new DesktopModeWindowDecoration(mContext,
+ return createWindowDecoration(taskInfo, new FakeMaximizeMenuFactory());
+ }
+
+ private DesktopModeWindowDecoration createWindowDecoration(
+ ActivityManager.RunningTaskInfo taskInfo,
+ MaximizeMenuFactory maximizeMenuFactory) {
+ final DesktopModeWindowDecoration windowDecor = new DesktopModeWindowDecoration(mContext,
mMockDisplayController, mMockShellTaskOrganizer, taskInfo, mMockSurfaceControl,
mMockHandler, mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
SurfaceControl.Builder::new, mMockTransactionSupplier,
WindowContainerTransaction::new, SurfaceControl::new,
- mMockSurfaceControlViewHostFactory);
+ mMockSurfaceControlViewHostFactory,
+ maximizeMenuFactory);
windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener,
mMockTouchEventListener, mMockTouchEventListener);
windowDecor.setExclusionRegionListener(mMockExclusionRegionListener);
@@ -499,8 +611,6 @@
.setTaskDescriptionBuilder(taskDescriptionBuilder)
.setVisible(visible)
.build();
- taskInfo.topActivityInfo = new ActivityInfo();
- taskInfo.topActivityInfo.applicationInfo = new ApplicationInfo();
taskInfo.realActivity = new ComponentName("com.android.wm.shell.windowdecor",
"DesktopModeWindowDecorationTests");
taskInfo.baseActivity = new ComponentName("com.android.wm.shell.windowdecor",
@@ -541,4 +651,27 @@
return false;
}
}
+
+ private static final class FakeMaximizeMenuFactory implements MaximizeMenuFactory {
+ private final MaximizeMenu mMaximizeMenu;
+
+ FakeMaximizeMenuFactory() {
+ this(mock(MaximizeMenu.class));
+ }
+
+ FakeMaximizeMenuFactory(MaximizeMenu menu) {
+ mMaximizeMenu = menu;
+ }
+
+ @NonNull
+ @Override
+ public MaximizeMenu create(@NonNull SyncTransactionQueue syncQueue,
+ @NonNull RootTaskDisplayAreaOrganizer rootTdaOrganizer,
+ @NonNull DisplayController displayController,
+ @NonNull ActivityManager.RunningTaskInfo taskInfo,
+ @NonNull Context decorWindowContext, @NonNull PointF menuPosition,
+ @NonNull Supplier<SurfaceControl.Transaction> transactionSupplier) {
+ return mMaximizeMenu;
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
index 86aded7..ac5aeec 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
@@ -27,6 +27,9 @@
import android.testing.AndroidTestingRunner
import android.view.Display
import android.window.WindowContainerToken
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.common.DisplayController
@@ -37,6 +40,7 @@
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertTrue
+import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -45,6 +49,7 @@
import org.mockito.Mockito.any
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import org.mockito.quality.Strictness
/**
* Tests for [DragPositioningCallbackUtility].
@@ -82,9 +87,13 @@
@Rule
val setFlagsRule = SetFlagsRule()
+ private lateinit var mockitoSession: StaticMockitoSession
+
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ mockitoSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java).startMocking()
whenever(taskToken.asBinder()).thenReturn(taskBinder)
whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
@@ -105,6 +114,11 @@
whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
}
+ @After
+ fun tearDown() {
+ mockitoSession.finishMocking()
+ }
+
@Test
fun testChangeBoundsDoesNotChangeHeightWhenLessThanMin() {
val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
@@ -252,7 +266,7 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeLessThanMin_shouldNotChangeBounds() {
- whenever(DesktopModeStatus.canEnterDesktopMode(mockContext)).thenReturn(true)
+ doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1)
val startingPoint =
PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat())
@@ -275,7 +289,7 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeAllowedSize_shouldChangeBounds() {
- whenever(DesktopModeStatus.canEnterDesktopMode(mockContext)).thenReturn(true)
+ doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1)
val startingPoint =
PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat())
@@ -361,7 +375,7 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun testChangeBoundsInDesktopMode_windowSizeExceedsStableBounds_shouldBeLimitedToDisplaySize() {
- whenever(DesktopModeStatus.canEnterDesktopMode(mockContext)).thenReturn(true)
+ doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
val startingPoint =
PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
OFF_CENTER_STARTING_BOUNDS.bottom.toFloat())
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index 901ca90..943c313 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -33,6 +33,7 @@
import android.window.TransitionInfo
import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
+import com.android.internal.jank.InteractionJankMonitor
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController
@@ -104,6 +105,8 @@
private lateinit var mockContext: Context
@Mock
private lateinit var mockResources: Resources
+ @Mock
+ private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
private lateinit var taskPositioner: VeiledResizeTaskPositioner
@@ -150,7 +153,8 @@
mockDisplayController,
mockDragStartListener,
mockTransactionFactory,
- mockTransitions
+ mockTransitions,
+ mockInteractionJankMonitor
)
}
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 77800a3..2fff4f5 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -212,6 +212,7 @@
"tests/AttributeResolution_test.cpp",
"tests/BigBuffer_test.cpp",
"tests/ByteBucketArray_test.cpp",
+ "tests/CombinedIterator_test.cpp",
"tests/Config_test.cpp",
"tests/ConfigDescription_test.cpp",
"tests/ConfigLocale_test.cpp",
@@ -267,6 +268,7 @@
cc_benchmark {
name: "libandroidfw_benchmarks",
defaults: ["libandroidfw_defaults"],
+ test_config: "tests/AndroidTest_Benchmarks.xml",
srcs: [
// Helpers/infra for benchmarking.
"tests/BenchMain.cpp",
@@ -282,7 +284,11 @@
"tests/Theme_bench.cpp",
],
shared_libs: common_test_libs,
- data: ["tests/data/**/*.apk"],
+ data: [
+ "tests/data/**/*.apk",
+ ":FrameworkResourcesSparseTestApp",
+ ":FrameworkResourcesNotSparseTestApp",
+ ],
}
cc_library {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 46f636e..822a387 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -23,9 +23,11 @@
#include <map>
#include <set>
#include <span>
+#include <utility>
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
+#include "androidfw/CombinedIterator.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/ResourceUtils.h"
#include "androidfw/Util.h"
@@ -1622,6 +1624,12 @@
Theme::~Theme() = default;
+static bool IsUndefined(const Res_value& value) {
+ // DATA_NULL_EMPTY (@empty) is a valid resource value and DATA_NULL_UNDEFINED represents
+ // an absence of a valid value.
+ return value.dataType == Res_value::TYPE_NULL && value.data != Res_value::DATA_NULL_EMPTY;
+}
+
base::expected<std::monostate, NullOrIOError> Theme::ApplyStyle(uint32_t resid, bool force) {
ATRACE_NAME("Theme::ApplyStyle");
@@ -1633,39 +1641,76 @@
// Merge the flags from this style.
type_spec_flags_ |= (*bag)->type_spec_flags;
+ //
+ // This function is the most expensive part of applying an frro to the existing app resources,
+ // and needs to be as efficient as possible.
+ // The data structure we're working with is two parallel sorted arrays of keys (resource IDs)
+ // and entries (resource value + some attributes).
+ // The styles get applied in sequence, starting with an empty set of attributes. Each style
+ // contains its values for the theme attributes, and gets applied in either normal or forced way:
+ // - normal way never overrides the existing attribute, so only unique style attributes are added
+ // - forced way overrides anything for that attribute, and if it's undefined it removes the
+ // previous value completely
+ //
+ // Style attributes come in a Bag data type - a sorted array of attributes with their values. This
+ // means we don't need to re-sort the attributes ever, and instead:
+ // - for an already existing attribute just skip it or apply the forced value
+ // - if the forced value is undefined, mark it undefined as well to get rid of it later
+ // - for a new attribute append it to the array, forming a new sorted section of new attributes
+ // past the end of the original ones (ignore undefined ones here)
+ // - inplace merge two sorted sections to form a single sorted array again.
+ // - run the last pass to remove all undefined elements
+ //
+ // Using this algorithm performs better than a repeated binary search + insert in the middle,
+ // as that keeps shifting the tail end of the arrays and wasting CPU cycles in memcpy().
+ //
+ const auto starting_size = keys_.size();
+ if (starting_size == 0) {
+ keys_.reserve((*bag)->entry_count);
+ entries_.reserve((*bag)->entry_count);
+ }
+ bool wrote_undefined = false;
for (auto it = begin(*bag); it != end(*bag); ++it) {
const uint32_t attr_res_id = it->key;
-
// If the resource ID passed in is not a style, the key can be some other identifier that is not
// a resource ID. We should fail fast instead of operating with strange resource IDs.
if (!is_valid_resid(attr_res_id)) {
return base::unexpected(std::nullopt);
}
-
- // DATA_NULL_EMPTY (@empty) is a valid resource value and DATA_NULL_UNDEFINED represents
- // an absence of a valid value.
- bool is_undefined = it->value.dataType == Res_value::TYPE_NULL &&
- it->value.data != Res_value::DATA_NULL_EMPTY;
+ const bool is_undefined = IsUndefined(it->value);
if (!force && is_undefined) {
continue;
}
-
- const auto key_it = std::lower_bound(keys_.begin(), keys_.end(), attr_res_id);
- const auto entry_it = entries_.begin() + (key_it - keys_.begin());
- if (key_it != keys_.end() && *key_it == attr_res_id) {
- if (is_undefined) {
- // DATA_NULL_UNDEFINED clears the value of the attribute in the theme only when `force` is
- // true.
- keys_.erase(key_it);
- entries_.erase(entry_it);
- } else if (force) {
+ const auto key_it = std::lower_bound(keys_.begin(), keys_.begin() + starting_size, attr_res_id);
+ if (key_it != keys_.begin() + starting_size && *key_it == attr_res_id) {
+ const auto entry_it = entries_.begin() + (key_it - keys_.begin());
+ if (force || IsUndefined(entry_it->value)) {
*entry_it = Entry{it->cookie, (*bag)->type_spec_flags, it->value};
+ wrote_undefined |= is_undefined;
}
- } else {
- keys_.insert(key_it, attr_res_id);
- entries_.insert(entry_it, Entry{it->cookie, (*bag)->type_spec_flags, it->value});
+ } else if (!is_undefined) {
+ keys_.emplace_back(attr_res_id);
+ entries_.emplace_back(it->cookie, (*bag)->type_spec_flags, it->value);
}
}
+
+ if (starting_size && keys_.size() != starting_size) {
+ std::inplace_merge(
+ CombinedIterator(keys_.begin(), entries_.begin()),
+ CombinedIterator(keys_.begin() + starting_size, entries_.begin() + starting_size),
+ CombinedIterator(keys_.end(), entries_.end()));
+ }
+ if (wrote_undefined) {
+ auto new_end = std::remove_if(CombinedIterator(keys_.begin(), entries_.begin()),
+ CombinedIterator(keys_.end(), entries_.end()),
+ [](const auto& pair) { return IsUndefined(pair.second.value); });
+ keys_.erase(new_end.it1, keys_.end());
+ entries_.erase(new_end.it2, entries_.end());
+ }
+ if (android::base::kEnableDChecks && !std::is_sorted(keys_.begin(), keys_.end())) {
+ ALOGW("Bag %u was unsorted in the apk?", unsigned(resid));
+ return base::unexpected(std::nullopt);
+ }
return {};
}
@@ -1691,6 +1736,9 @@
return std::nullopt;
}
const auto entry_it = entries_.begin() + (key_it - keys_.begin());
+ if (IsUndefined(entry_it->value)) {
+ return std::nullopt;
+ }
type_spec_flags |= entry_it->type_spec_flags;
if (entry_it->value.dataType == Res_value::TYPE_ATTRIBUTE) {
resid = entry_it->value.data;
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index 17a8ba6..ac46bc5 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -280,9 +280,9 @@
private:
SelectedValue(uint8_t value_type, Res_value::data_type value_data, ApkAssetsCookie cookie,
- uint32_t type_flags, uint32_t resid, const ResTable_config& config) :
+ uint32_t type_flags, uint32_t resid, ResTable_config config) :
cookie(cookie), data(value_data), type(value_type), flags(type_flags),
- resid(resid), config(config) {};
+ resid(resid), config(std::move(config)) {}
};
// Retrieves the best matching resource value with ID `resid`.
diff --git a/libs/androidfw/include/androidfw/CombinedIterator.h b/libs/androidfw/include/androidfw/CombinedIterator.h
new file mode 100644
index 0000000..4ff6a7d
--- /dev/null
+++ b/libs/androidfw/include/androidfw/CombinedIterator.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+#pragma once
+
+#include <compare>
+#include <iterator>
+#include <utility>
+
+namespace android {
+
+namespace detail {
+// A few useful aliases to not repeat them everywhere
+template <class It1, class It2>
+using Value = std::pair<typename std::iterator_traits<It1>::value_type,
+ typename std::iterator_traits<It2>::value_type>;
+
+template <class It1, class It2>
+using BaseRefPair = std::pair<typename std::iterator_traits<It1>::reference,
+ typename std::iterator_traits<It2>::reference>;
+
+template <class It1, class It2>
+struct RefPair : BaseRefPair<It1, It2> {
+ using Base = BaseRefPair<It1, It2>;
+ using Value = detail::Value<It1, It2>;
+
+ RefPair(It1 it1, It2 it2) : Base(*it1, *it2) {
+ }
+
+ RefPair& operator=(const Value& v) {
+ this->first = v.first;
+ this->second = v.second;
+ return *this;
+ }
+ operator Value() const {
+ return Value(this->first, this->second);
+ }
+ bool operator==(const RefPair& other) {
+ return this->first == other.first;
+ }
+ bool operator==(const Value& other) {
+ return this->first == other.first;
+ }
+ std::strong_ordering operator<=>(const RefPair& other) const {
+ return this->first <=> other.first;
+ }
+ std::strong_ordering operator<=>(const Value& other) const {
+ return this->first <=> other.first;
+ }
+ friend void swap(RefPair& l, RefPair& r) {
+ using std::swap;
+ swap(l.first, r.first);
+ swap(l.second, r.second);
+ }
+};
+
+template <class It1, class It2>
+struct RefPairPtr {
+ RefPair<It1, It2> value;
+
+ RefPair<It1, It2>* operator->() const {
+ return &value;
+ }
+};
+} // namespace detail
+
+//
+// CombinedIterator - a class to combine two iterators to process them as a single iterator to a
+// pair of values. Useful for processing a data structure of "struct of arrays", replacing
+// array of structs for cache locality.
+//
+// The value type is a pair of copies of the values of each iterator, and the reference is a
+// pair of references to the corresponding values. Comparison only compares the first element,
+// making it most useful for using on data like (vector<Key>, vector<Value>) for binary searching,
+// sorting both together and so on.
+//
+// The class is designed for handling arrays, so it requires random access iterators as an input.
+//
+
+template <class It1, class It2>
+requires std::random_access_iterator<It1> && std::random_access_iterator<It2>
+struct CombinedIterator {
+ typedef detail::Value<It1, It2> value_type;
+ typedef detail::RefPair<It1, It2> reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef detail::RefPairPtr<It1, It2> pointer;
+ typedef std::random_access_iterator_tag iterator_category;
+
+ CombinedIterator(It1 it1 = {}, It2 it2 = {}) : it1(it1), it2(it2) {
+ }
+
+ bool operator<(const CombinedIterator& other) const {
+ return it1 < other.it1;
+ }
+ bool operator<=(const CombinedIterator& other) const {
+ return it1 <= other.it1;
+ }
+ bool operator>(const CombinedIterator& other) const {
+ return it1 > other.it1;
+ }
+ bool operator>=(const CombinedIterator& other) const {
+ return it1 >= other.it1;
+ }
+ bool operator==(const CombinedIterator& other) const {
+ return it1 == other.it1;
+ }
+ pointer operator->() const {
+ return pointer{{it1, it2}};
+ }
+ reference operator*() const {
+ return {it1, it2};
+ }
+ reference operator[](difference_type n) const {
+ return {it1 + n, it2 + n};
+ }
+
+ CombinedIterator& operator++() {
+ ++it1;
+ ++it2;
+ return *this;
+ }
+ CombinedIterator operator++(int) {
+ const auto res = *this;
+ ++*this;
+ return res;
+ }
+ CombinedIterator& operator--() {
+ --it1;
+ --it2;
+ return *this;
+ }
+ CombinedIterator operator--(int) {
+ const auto res = *this;
+ --*this;
+ return res;
+ }
+ CombinedIterator& operator+=(difference_type n) {
+ it1 += n;
+ it2 += n;
+ return *this;
+ }
+ CombinedIterator operator+(difference_type n) const {
+ CombinedIterator res = *this;
+ return res += n;
+ }
+
+ CombinedIterator& operator-=(difference_type n) {
+ it1 -= n;
+ it2 -= n;
+ return *this;
+ }
+ CombinedIterator operator-(difference_type n) const {
+ CombinedIterator res = *this;
+ return res -= n;
+ }
+ difference_type operator-(const CombinedIterator& other) {
+ return it1 - other.it1;
+ }
+
+ It1 it1;
+ It2 it2;
+};
+
+} // namespace android
diff --git a/libs/androidfw/tests/AndroidTest_Benchmarks.xml b/libs/androidfw/tests/AndroidTest_Benchmarks.xml
new file mode 100644
index 0000000..e61e46f
--- /dev/null
+++ b/libs/androidfw/tests/AndroidTest_Benchmarks.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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.
+-->
+<configuration description="Runs libandroidfw_benchmarks and libandroidfw_tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native-metric" />
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="libandroidfw_benchmarks->/data/local/tmp/libandroidfw_benchmarks" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+ <option name="native-benchmark-device-path" value="/data/local/tmp" />
+ <option name="benchmark-module-name" value="libandroidfw_benchmarks" />
+ <!-- The GoogleBenchmarkTest class ordinarily expects every file in the benchmark's
+ directory (recursively) to be a google-benchmark binary, so we need this setting to
+ avoid failing on the test data files. -->
+ <option name="file-exclusion-filter-regex" value=".*\.(apk|config)$" />
+ </test>
+</configuration>
\ No newline at end of file
diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp
index 2caa98c..136f5ea 100644
--- a/libs/androidfw/tests/AssetManager2_bench.cpp
+++ b/libs/androidfw/tests/AssetManager2_bench.cpp
@@ -37,7 +37,7 @@
static void BM_AssetManagerLoadAssets(benchmark::State& state) {
std::string path = GetTestDataPath() + "/basic/basic.apk";
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
auto apk = ApkAssets::Load(path);
AssetManager2 assets;
assets.SetApkAssets({apk});
@@ -47,7 +47,7 @@
static void BM_AssetManagerLoadAssetsOld(benchmark::State& state) {
String8 path((GetTestDataPath() + "/basic/basic.apk").data());
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
AssetManager assets;
assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */,
false /* isSystemAsset */);
@@ -60,7 +60,7 @@
static void BM_AssetManagerLoadFrameworkAssets(benchmark::State& state) {
std::string path = kFrameworkPath;
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
auto apk = ApkAssets::Load(path);
AssetManager2 assets;
assets.SetApkAssets({apk});
@@ -70,7 +70,7 @@
static void BM_AssetManagerLoadFrameworkAssetsOld(benchmark::State& state) {
String8 path(kFrameworkPath);
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
AssetManager assets;
assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */,
false /* isSystemAsset */);
@@ -138,7 +138,7 @@
AssetManager2 assets;
assets.SetApkAssets({apk});
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
auto bag = assets.GetBag(app::R::style::StyleTwo);
if (!bag.has_value()) {
state.SkipWithError("Failed to load get bag");
@@ -165,7 +165,7 @@
const ResTable& table = assets.getResources(true);
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
const ResTable::bag_entry* bag_begin;
const ssize_t N = table.lockBag(app::R::style::StyleTwo, &bag_begin);
const ResTable::bag_entry* const bag_end = bag_begin + N;
@@ -190,7 +190,7 @@
AssetManager2 assets;
assets.SetApkAssets({apk});
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
std::set<std::string> locales =
assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/);
benchmark::DoNotOptimize(locales);
@@ -208,7 +208,7 @@
const ResTable& table = assets.getResources(true);
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
Vector<String8> locales;
table.getLocales(&locales, true /*includeSystemLocales*/, true /*mergeEquivalentLangs*/);
benchmark::DoNotOptimize(locales);
@@ -231,7 +231,7 @@
std::vector<ResTable_config> configs;
configs.push_back(config);
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
configs[0].sdkVersion = ~configs[0].sdkVersion;
assets.SetConfigurations(configs);
}
@@ -251,7 +251,7 @@
ResTable_config config;
memset(&config, 0, sizeof(config));
- while (state.KeepRunning()) {
+ for (auto&& _ : state) {
config.sdkVersion = ~config.sdkVersion;
assets.setConfiguration(config);
}
diff --git a/libs/androidfw/tests/BenchmarkHelpers.cpp b/libs/androidfw/tests/BenchmarkHelpers.cpp
index 8b883f4..e3fc0a0 100644
--- a/libs/androidfw/tests/BenchmarkHelpers.cpp
+++ b/libs/androidfw/tests/BenchmarkHelpers.cpp
@@ -28,7 +28,7 @@
for (const std::string& path : paths) {
if (!assetmanager.addAssetPath(String8(path.c_str()), nullptr /* cookie */,
false /* appAsLib */, false /* isSystemAssets */)) {
- state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str());
+ state.SkipWithError(base::StringPrintf("Failed to old-load assets %s", path.c_str()).c_str());
return;
}
}
@@ -57,7 +57,7 @@
for (const std::string& path : paths) {
auto apk = ApkAssets::Load(path);
if (apk == nullptr) {
- state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str());
+ state.SkipWithError(base::StringPrintf("Failed to new-load assets %s", path.c_str()).c_str());
return;
}
apk_assets.push_back(std::move(apk));
diff --git a/libs/androidfw/tests/CombinedIterator_test.cpp b/libs/androidfw/tests/CombinedIterator_test.cpp
new file mode 100644
index 0000000..c1228f3
--- /dev/null
+++ b/libs/androidfw/tests/CombinedIterator_test.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#include "androidfw/CombinedIterator.h"
+
+#include <algorithm>
+#include <string>
+#include <strstream>
+#include <utility>
+#include <vector>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace android {
+
+template <class Coll>
+std::string toString(const Coll& coll) {
+ std::stringstream res;
+ res << "(" << std::size(coll) << ")";
+ if (std::size(coll)) {
+ res << "{" << coll[0];
+ for (int i = 1; i != std::size(coll); ++i) {
+ res << "," << coll[i];
+ }
+ res << "}";
+ }
+ return res.str();
+}
+
+template <class Coll>
+void AssertCollectionEq(const Coll& first, const Coll& second) {
+ ASSERT_EQ(std::size(first), std::size(second))
+ << "first: " << toString(first) << ", second: " << toString(second);
+ for (int i = 0; i != std::size(first); ++i) {
+ ASSERT_EQ(first[i], second[i])
+ << "index: " << i << " first: " << toString(first) << ", second: " << toString(second);
+ }
+}
+
+TEST(CombinedIteratorTest, Sorting) {
+ std::vector<int> v1 = {2, 1, 3, 4, 0};
+ std::vector<int> v2 = {20, 10, 30, 40, 0};
+
+ std::sort(CombinedIterator(v1.begin(), v2.begin()), CombinedIterator(v1.end(), v2.end()));
+
+ ASSERT_EQ(v1.size(), v2.size());
+ ASSERT_TRUE(std::is_sorted(v1.begin(), v1.end()));
+ ASSERT_TRUE(std::is_sorted(v2.begin(), v2.end()));
+ AssertCollectionEq(v1, {0, 1, 2, 3, 4});
+ AssertCollectionEq(v2, {0, 10, 20, 30, 40});
+}
+
+TEST(CombinedIteratorTest, Removing) {
+ std::vector<int> v1 = {1, 2, 3, 4, 5, 5, 5, 6};
+ std::vector<int> v2 = {10, 20, 30, 40, 50, 50, 50, 60};
+
+ auto newEnd =
+ std::remove_if(CombinedIterator(v1.begin(), v2.begin()), CombinedIterator(v1.end(), v2.end()),
+ [](auto&& pair) { return pair.first >= 3 && pair.first <= 5; });
+
+ ASSERT_EQ(newEnd.it1, v1.begin() + 3);
+ ASSERT_EQ(newEnd.it2, v2.begin() + 3);
+
+ v1.erase(newEnd.it1, v1.end());
+ AssertCollectionEq(v1, {1, 2, 6});
+ v2.erase(newEnd.it2, v2.end());
+ AssertCollectionEq(v2, {10, 20, 60});
+}
+
+TEST(CombinedIteratorTest, InplaceMerge) {
+ std::vector<int> v1 = {1, 3, 4, 7, 2, 5, 6};
+ std::vector<int> v2 = {10, 30, 40, 70, 20, 50, 60};
+
+ std::inplace_merge(CombinedIterator(v1.begin(), v2.begin()),
+ CombinedIterator(v1.begin() + 4, v2.begin() + 4),
+ CombinedIterator(v1.end(), v2.end()));
+ ASSERT_TRUE(std::is_sorted(v1.begin(), v1.end()));
+ ASSERT_TRUE(std::is_sorted(v2.begin(), v2.end()));
+
+ AssertCollectionEq(v1, {1, 2, 3, 4, 5, 6, 7});
+ AssertCollectionEq(v2, {10, 20, 30, 40, 50, 60, 70});
+}
+
+} // namespace android
diff --git a/libs/androidfw/tests/Theme_bench.cpp b/libs/androidfw/tests/Theme_bench.cpp
index dfbb5a7..bf89617 100644
--- a/libs/androidfw/tests/Theme_bench.cpp
+++ b/libs/androidfw/tests/Theme_bench.cpp
@@ -27,6 +27,10 @@
constexpr const static uint32_t kStyleId = 0x01030237u; // android:style/Theme.Material.Light
constexpr const static uint32_t kAttrId = 0x01010030u; // android:attr/colorForeground
+constexpr const static uint32_t kStyle2Id = 0x01030224u; // android:style/Theme.Material
+constexpr const static uint32_t kStyle3Id = 0x0103024du; // android:style/Widget.Material
+constexpr const static uint32_t kStyle4Id = 0x0103028eu; // android:style/Widget.Material.Light
+
static void BM_ThemeApplyStyleFramework(benchmark::State& state) {
auto apk = ApkAssets::Load(kFrameworkPath);
if (apk == nullptr) {
@@ -61,6 +65,32 @@
}
BENCHMARK(BM_ThemeApplyStyleFrameworkOld);
+static void BM_ThemeRebaseFramework(benchmark::State& state) {
+ auto apk = ApkAssets::Load(kFrameworkPath);
+ if (apk == nullptr) {
+ state.SkipWithError("Failed to load assets");
+ return;
+ }
+
+ AssetManager2 assets;
+ assets.SetApkAssets({apk});
+
+ // Create two arrays of styles to switch between back and forth.
+ const uint32_t styles1[] = {kStyle2Id, kStyleId, kStyle3Id};
+ const uint8_t force1[std::size(styles1)] = {false, true, false};
+ const uint32_t styles2[] = {kStyleId, kStyle2Id, kStyle4Id, kStyle3Id};
+ const uint8_t force2[std::size(styles2)] = {false, true, true, false};
+ const auto theme = assets.NewTheme();
+ // Initialize the theme to make the first iteration the same as the rest.
+ theme->Rebase(&assets, styles1, force1, std::size(force1));
+
+ while (state.KeepRunning()) {
+ theme->Rebase(&assets, styles2, force2, std::size(force2));
+ theme->Rebase(&assets, styles1, force1, std::size(force1));
+ }
+}
+BENCHMARK(BM_ThemeRebaseFramework);
+
static void BM_ThemeGetAttribute(benchmark::State& state) {
auto apk = ApkAssets::Load(kFrameworkPath);
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e134c23..124f1f0 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -7007,6 +7007,23 @@
}
/**
+ * Check whether a user can mute this stream type from a given UI element.
+ *
+ * <p>Only useful for volume controllers.
+ *
+ * @param streamType type of stream to check if it's mutable from UI
+ *
+ * @hide
+ */
+ public boolean isStreamMutableByUi(int streamType) {
+ try {
+ return getService().isStreamMutableByUi(streamType);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Only useful for volume controllers.
* @hide
*/
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index c263245..fd71f86 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -44,8 +44,9 @@
* Add the UID for a new assistant service
*
* @param uid UID of the newly available assistants
+ * @param owningUid UID of the actual assistant app, if {@code uid} is a isolated proc
*/
- public abstract void addAssistantServiceUid(int uid);
+ public abstract void addAssistantServiceUid(int uid, int owningUid);
/**
* Remove the UID for an existing assistant service
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index c8b9da5..08cc126 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -305,6 +305,8 @@
boolean isStreamAffectedByMute(int streamType);
+ boolean isStreamMutableByUi(int streamType);
+
void disableSafeMediaVolume(String callingPackage);
oneway void lowerVolumeToRs1(String callingPackage);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 3ba0d59..8acaf3b 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -5143,9 +5143,9 @@
* of negative QP and positive QP are chosen wisely, the overall viewing experience can be
* improved.
* <p>
- * If byte array size is too small than the expected size, components may ignore the
- * configuration silently. If the byte array exceeds the expected size, components shall use
- * the initial portion and ignore the rest.
+ * If byte array size is smaller than the expected size, components will ignore the
+ * configuration and print an error message. If the byte array exceeds the expected size,
+ * components will use the initial portion and ignore the rest.
* <p>
* The scope of this key is throughout the encoding session until it is reconfigured during
* running state.
@@ -5159,7 +5159,8 @@
* Set the region of interest as QpOffset-Rects on the next queued input frame.
* <p>
* The associated value is a String in the format "Top1,Left1-Bottom1,Right1=Offset1;Top2,
- * Left2-Bottom2,Right2=Offset2;...". Co-ordinates (Top, Left), (Top, Right), (Bottom, Left)
+ * Left2-Bottom2,Right2=Offset2;...". If the configuration doesn't follow this pattern,
+ * it will be ignored. Co-ordinates (Top, Left), (Top, Right), (Bottom, Left)
* and (Bottom, Right) form the vertices of bounding box of region of interest in pixels.
* Pixel (0, 0) points to the top-left corner of the frame. Offset is the suggested
* quantization parameter (QP) offset of the blocks in the bounding box. The bounding box
@@ -5171,9 +5172,10 @@
* negative QP and positive QP are chosen wisely, the overall viewing experience can be
* improved.
* <p>
- * If Roi rect is not valid that is bounding box width is < 0 or bounding box height is < 0,
- * components may ignore the configuration silently. If Roi rect extends outside frame
- * boundaries, then rect shall be clamped to the frame boundaries.
+ * If roi (region of interest) rect is outside the frame boundaries, that is, left < 0 or
+ * top < 0 or right > width or bottom > height, then rect shall be clamped to the frame
+ * boundaries. If roi rect is not valid, that is left > right or top > bottom, then the
+ * parameter setting is ignored.
* <p>
* The scope of this key is throughout the encoding session until it is reconfigured during
* running state.
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index e619e1c..7f487e5 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -79,7 +79,6 @@
"libcamera_client",
"libmtp",
"libpiex",
- "libprocessgroup",
"libandroidfw",
"libhidlallocatorutils",
"libhidlbase",
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
index 1325fc1..028c97e 100644
--- a/media/tests/MediaFrameworkTest/Android.bp
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -24,6 +24,7 @@
"flag-junit",
"testng",
"truth",
+ "collector-device-lib-platform",
],
jni_libs: [
"libdexmakerjvmtiagent",
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
index 00068bd..102d21a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
@@ -16,6 +16,8 @@
package com.android.mediaframeworktest.helpers;
+import android.content.AttributionSourceState;
+import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
@@ -2227,4 +2229,24 @@
else
return new Size(width, height);
}
+
+ /**
+ * Constructs an AttributionSourceState with only the uid, pid, and deviceId fields set
+ *
+ * <p>This method is a temporary stopgap in the transition to using AttributionSource. Currently
+ * AttributionSourceState is only used as a vehicle for passing deviceId, uid, and pid
+ * arguments.</p>
+ */
+ public static AttributionSourceState getClientAttribution(Context context) {
+ // TODO: Send the full contextAttribution over aidl, remove USE_CALLING_*
+ AttributionSourceState contextAttribution =
+ context.getAttributionSource().asState();
+ AttributionSourceState clientAttribution =
+ new AttributionSourceState();
+ clientAttribution.uid = -1; // USE_CALLING_UID
+ clientAttribution.pid = -1; // USE_CALLING_PID
+ clientAttribution.deviceId = contextAttribution.deviceId;
+ clientAttribution.next = new AttributionSourceState[0];
+ return clientAttribution;
+ }
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 353366d..ad3374a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -19,6 +19,7 @@
import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
import static android.content.Context.DEVICE_ID_DEFAULT;
+import android.content.AttributionSourceState;
import android.hardware.CameraInfo;
import android.hardware.ICamera;
import android.hardware.ICameraClient;
@@ -38,6 +39,8 @@
import androidx.test.filters.SmallTest;
+import com.android.mediaframeworktest.helpers.CameraTestUtils;
+
/**
* <p>
* Junit / Instrumentation test case for the camera2 api
@@ -78,8 +81,10 @@
@SmallTest
public void testNumberOfCameras() throws Exception {
+ AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+ clientAttribution.deviceId = DEVICE_ID_DEFAULT;
int numCameras = mUtils.getCameraService().getNumberOfCameras(CAMERA_TYPE_ALL,
- DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+ clientAttribution, DEVICE_POLICY_DEFAULT);
assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(),
numCameras >= mUtils.getGuessedNumCameras());
Log.v(TAG, "Number of cameras " + numCameras);
@@ -87,9 +92,11 @@
@SmallTest
public void testCameraInfo() throws Exception {
+ AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+ clientAttribution.deviceId = DEVICE_ID_DEFAULT;
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId,
- ICameraService.ROTATION_OVERRIDE_NONE, DEVICE_ID_DEFAULT,
+ ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution,
DEVICE_POLICY_DEFAULT);
assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
assertTrue("Orientation was not set for camera " + cameraId,
@@ -154,6 +161,10 @@
@SmallTest
public void testConnect() throws Exception {
+ AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+ clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+ clientAttribution.uid = ICameraService.USE_CALLING_UID;
+ clientAttribution.pid = ICameraService.USE_CALLING_PID;
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
ICameraClient dummyCallbacks = new DummyCameraClient();
@@ -162,12 +173,10 @@
ICamera cameraUser = mUtils.getCameraService()
.connect(dummyCallbacks, cameraId, clientPackageName,
- ICameraService.USE_CALLING_UID,
- ICameraService.USE_CALLING_PID,
getContext().getApplicationInfo().targetSdkVersion,
ICameraService.ROTATION_OVERRIDE_NONE,
/*forceSlowJpegMode*/false,
- DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+ clientAttribution, DEVICE_POLICY_DEFAULT);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
Log.v(TAG, String.format("Camera %s connected", cameraId));
@@ -260,14 +269,18 @@
String clientPackageName = getContext().getPackageName();
String clientAttributionTag = getContext().getAttributionTag();
+ AttributionSourceState clientAttribution =
+ CameraTestUtils.getClientAttribution(mContext);
+ clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+ clientAttribution.uid = ICameraService.USE_CALLING_UID;
ICameraDeviceUser cameraUser =
mUtils.getCameraService().connectDevice(
dummyCallbacks, String.valueOf(cameraId),
clientPackageName, clientAttributionTag,
- ICameraService.USE_CALLING_UID, 0 /*oomScoreOffset*/,
+ 0 /*oomScoreOffset*/,
getContext().getApplicationInfo().targetSdkVersion,
- ICameraService.ROTATION_OVERRIDE_NONE, DEVICE_ID_DEFAULT,
+ ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution,
DEVICE_POLICY_DEFAULT);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 6cf2a41..0ab1ee9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
+import android.content.AttributionSourceState;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.ICameraService;
@@ -54,6 +55,7 @@
import androidx.test.filters.SmallTest;
import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
+import com.android.mediaframeworktest.helpers.CameraTestUtils;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
@@ -245,10 +247,14 @@
mMockCb = spy(dummyCallbacks);
+ AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+ clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+ clientAttribution.uid = ICameraService.USE_CALLING_UID;
+
mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
- clientPackageName, clientAttributionTag, ICameraService.USE_CALLING_UID,
+ clientPackageName, clientAttributionTag,
/*oomScoreOffset*/0, getContext().getApplicationInfo().targetSdkVersion,
- ICameraService.ROTATION_OVERRIDE_NONE, DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+ ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution, DEVICE_POLICY_DEFAULT);
assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
@@ -414,10 +420,13 @@
@SmallTest
public void testCameraCharacteristics() throws RemoteException {
+ AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+ clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+
CameraMetadataNative info = mUtils.getCameraService().getCameraCharacteristics(mCameraId,
getContext().getApplicationInfo().targetSdkVersion,
ICameraService.ROTATION_OVERRIDE_NONE,
- DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+ clientAttribution, DEVICE_POLICY_DEFAULT);
assertFalse(info.isEmpty());
assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 7e5bef1..e91c7a9 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -244,6 +244,12 @@
ALOGE("%s: targetDurationNanos must be positive", __FUNCTION__);
return EINVAL;
}
+ {
+ std::scoped_lock lock(sHintMutex);
+ if (mTargetDurationNanos == targetDurationNanos) {
+ return 0;
+ }
+ }
ndk::ScopedAStatus ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
if (!ret.isOk()) {
ALOGE("%s: HintSession updateTargetWorkDuration failed: %s", __FUNCTION__,
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 78a5357..d19fa98 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -159,6 +159,10 @@
int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
EXPECT_EQ(0, result);
+ // subsequent call with same target should be ignored but return no error
+ result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+ EXPECT_EQ(0, result);
+
usleep(2); // Sleep for longer than preferredUpdateRateNanos.
int64_t actualDurationNanos = 20;
std::vector<int64_t> actualDurations;
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index b242a76..95945d7 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -110,3 +110,11 @@
bug: "321311407"
}
+flag {
+ name: "nfc_persist_log"
+ is_exported: true
+ namespace: "nfc"
+ description: "Enable NFC persistent log support"
+ bug: "321310044"
+}
+
diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml
index d9afe873..bfc2fec 100644
--- a/packages/CarrierDefaultApp/res/values-fa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml
@@ -5,7 +5,7 @@
<string name="android_system_label" msgid="2797790869522345065">"شرکت مخابراتی دستگاه همراه"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"داده تلفن همراه تمام شده است"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"داده شبکه تلفن همراه شما غیرفعال شده است"</string>
- <string name="portal_notification_detail" msgid="2295729385924660881">"برای رفتن به وبسایت %s، ضربه بزنید"</string>
+ <string name="portal_notification_detail" msgid="2295729385924660881">"برای رفتن به وبسایت %s، تکضرب بزنید"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"لطفاً با ارائهدهنده خدمات %s خود تماس بگیرید"</string>
<string name="no_mobile_data_connection_title" msgid="7449525772416200578">"بدون اتصال داده دستگاه همراه"</string>
<string name="no_mobile_data_connection" msgid="544980465184147010">"افزودن طرح داده یا فراگردی ازطریق %s"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index e3dd4cb..9106721 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -20,7 +20,7 @@
<string name="confirmation_title" msgid="2244241995958340998">"هل تريد السماح لـ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>؟"</string>
<string name="profile_name_watch" msgid="576290739483672360">"الساعة"</string>
<string name="chooser_title_non_profile" msgid="6035023914517087400">"اختيار جهاز ليديره تطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string>
- <string name="chooser_title" msgid="2235819929238267637">"اختيار \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" لإعداده"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"اختيار \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" للإعداد"</string>
<string name="summary_watch" msgid="7962014927042971830">"سيتم السماح لهذا التطبيق بمزامنة المعلومات، مثلاً اسم المتصل، والوصول إلى هذه الأذونات على \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"هل تريد السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بإدارة <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>؟"</string>
<string name="profile_name_glasses" msgid="3506504967216601277">"جهاز"</string>
diff --git a/packages/CrashRecovery/aconfig/flags.aconfig b/packages/CrashRecovery/aconfig/flags.aconfig
index 80412321..225f8c6 100644
--- a/packages/CrashRecovery/aconfig/flags.aconfig
+++ b/packages/CrashRecovery/aconfig/flags.aconfig
@@ -26,8 +26,8 @@
}
flag {
- name: "reenable_settings_resets"
+ name: "deprecate_flags_and_settings_resets"
namespace: "modularization"
- description: "Re-enables settings resets only, deletes flag resets"
+ description: "Deletes flag and settings resets"
bug: "333847376"
}
diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml
index 6147ccc..6e6c22a 100644
--- a/packages/CredentialManager/res/values-fa/strings.xml
+++ b/packages/CredentialManager/res/values-fa/strings.xml
@@ -86,7 +86,7 @@
<string name="button_label_view_more" msgid="3429098227286495651">"مشاهده موارد بیشتر"</string>
<string name="get_dialog_heading_for_username" msgid="3456868514554204776">"برای <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
<string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"مدیران گذرواژه قفلشده"</string>
- <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"برای باز کردن قفل ضربه بزنید"</string>
+ <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"برای باز کردن قفل تکضرب بزنید"</string>
<string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"اطلاعات ورود به سیستم موجود نیست"</string>
<string name="no_sign_in_info_in" msgid="2641118151920288356">"هیچ اطلاعات ورود به سیستمی در <xliff:g id="SOURCE">%1$s</xliff:g> وجود ندارد"</string>
<string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"مدیریت ورود به سیستمها"</string>
diff --git a/packages/InputDevices/AndroidManifest.xml b/packages/InputDevices/AndroidManifest.xml
index da8c0d3..01b0bc7 100644
--- a/packages/InputDevices/AndroidManifest.xml
+++ b/packages/InputDevices/AndroidManifest.xml
@@ -19,5 +19,23 @@
<meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
android:resource="@xml/keyboard_layouts" />
</receiver>
+
+ <receiver android:name=".KeyGlyphMapProvider"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS" />
+ </intent-filter>
+ <meta-data android:name="android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"
+ android:resource="@xml/keyboard_glyph_maps" />
+ </receiver>
+
+ <receiver android:name=".OverlayKeyGlyphMapProvider"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS" />
+ </intent-filter>
+ <meta-data android:name="android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"
+ android:resource="@xml/keyboard_glyph_maps_overlay" />
+ </receiver>
</application>
</manifest>
diff --git a/packages/InputDevices/res/xml/keyboard_glyph_maps.xml b/packages/InputDevices/res/xml/keyboard_glyph_maps.xml
new file mode 100644
index 0000000..b7a6f3f
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_glyph_maps.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2024 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.
+ -->
+<keyboard-glyph-maps xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- <key-glyph-map-->
+<!-- android:glyphMap="@xml/xyz_glyph_map"-->
+<!-- android:vendorId="0x1234"-->
+<!-- android:productId="0x3456" />-->
+</keyboard-glyph-maps>
\ No newline at end of file
diff --git a/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml b/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml
new file mode 100644
index 0000000..7c036eb
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2024 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.
+ -->
+<keyboard-glyph-maps xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- NOTE: This is reserved for glyph maps to be provided using RRO. For providing glyph maps in
+ AOSP use key_glyph_maps.xml instead -->
+</keyboard-glyph-maps>
\ No newline at end of file
diff --git a/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java b/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java
new file mode 100644
index 0000000..6b508dd
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class KeyGlyphMapProvider extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Nothing to do at this time.
+ }
+}
diff --git a/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java b/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java
new file mode 100644
index 0000000..13b5b42
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class OverlayKeyGlyphMapProvider extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Nothing to do at this time.
+ }
+}
diff --git a/packages/PackageInstaller/res/layout/install_content_view.xml b/packages/PackageInstaller/res/layout/install_content_view.xml
index 524a88a..affcca1 100644
--- a/packages/PackageInstaller/res/layout/install_content_view.xml
+++ b/packages/PackageInstaller/res/layout/install_content_view.xml
@@ -34,7 +34,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/message_staging" />
<ProgressBar
@@ -57,7 +57,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/installing" />
<ProgressBar
@@ -74,7 +74,7 @@
android:id="@+id/install_confirm_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_confirm_question"
android:visibility="invisible"
android:scrollbars="vertical" />
@@ -83,7 +83,7 @@
android:id="@+id/install_confirm_question_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_confirm_question_update"
android:visibility="invisible"
android:scrollbars="vertical" />
@@ -92,7 +92,7 @@
android:id="@+id/install_success"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_done"
android:visibility="invisible" />
@@ -100,7 +100,7 @@
android:id="@+id/install_failed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_failed"
android:visibility="invisible" />
@@ -108,7 +108,7 @@
android:id="@+id/install_failed_blocked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_failed_blocked"
android:visibility="invisible" />
@@ -116,7 +116,7 @@
android:id="@+id/install_failed_conflict"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_failed_conflict"
android:visibility="invisible" />
@@ -124,7 +124,7 @@
android:id="@+id/install_failed_incompatible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_failed_incompatible"
android:visibility="invisible" />
@@ -132,7 +132,7 @@
android:id="@+id/install_failed_invalid_apk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
android:text="@string/install_failed_invalid_apk"
android:visibility="invisible" />
diff --git a/packages/PackageInstaller/res/layout/uninstall_content_view.xml b/packages/PackageInstaller/res/layout/uninstall_content_view.xml
index 434e333..d5c5d8b 100644
--- a/packages/PackageInstaller/res/layout/uninstall_content_view.xml
+++ b/packages/PackageInstaller/res/layout/uninstall_content_view.xml
@@ -22,32 +22,32 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:theme="?android:attr/alertDialogTheme"
- android:orientation="vertical"
- android:paddingTop="8dp"
- android:paddingStart="?android:attr/dialogPreferredPadding"
- android:paddingEnd="?android:attr/dialogPreferredPadding"
- android:clipToPadding="false">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:theme="?android:attr/alertDialogTheme"
+ android:orientation="vertical"
+ android:paddingTop="8dp"
+ android:paddingStart="?android:attr/dialogPreferredPadding"
+ android:paddingEnd="?android:attr/dialogPreferredPadding"
+ android:clipToPadding="false">
- <TextView
- android:id="@+id/message"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead" />
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle" />
- <CheckBox
- android:id="@+id/keepData"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginStart="-8dp"
- android:paddingLeft="8sp"
- android:visibility="gone"
- style="@android:style/TextAppearance.Material.Subhead" />
+ <CheckBox
+ android:id="@+id/keepData"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="-8dp"
+ android:paddingStart="8sp"
+ android:paddingEnd="0sp"
+ android:visibility="gone"
+ style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle" />
- </LinearLayout>
+ </LinearLayout>
</ScrollView>
diff --git a/packages/PackageInstaller/res/values-night/themes.xml b/packages/PackageInstaller/res/values-night/themes.xml
index a5b82b3..37588ad 100644
--- a/packages/PackageInstaller/res/values-night/themes.xml
+++ b/packages/PackageInstaller/res/values-night/themes.xml
@@ -19,7 +19,6 @@
<style name="Theme.AlertDialogActivity"
parent="@android:style/Theme.DeviceDefault.Dialog.Alert">
- <item name="alertDialogStyle">@style/AlertDialog</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowAnimationStyle">@null</item>
diff --git a/packages/PackageInstaller/res/values/themes.xml b/packages/PackageInstaller/res/values/themes.xml
index f5af510..aa48712 100644
--- a/packages/PackageInstaller/res/values/themes.xml
+++ b/packages/PackageInstaller/res/values/themes.xml
@@ -19,7 +19,6 @@
<style name="Theme.AlertDialogActivity"
parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert">
- <item name="alertDialogStyle">@style/AlertDialog</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowAnimationStyle">@null</item>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index e0398aa..824dd4a 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -330,7 +330,8 @@
// data we still want to count it as "installed".
mAppInfo = mPm.getApplicationInfo(pkgName,
PackageManager.MATCH_UNINSTALLED_PACKAGES);
- if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ // If the package is archived, treat it as update case.
+ if (!mAppInfo.isArchived && (mAppInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
mAppInfo = null;
}
} catch (NameNotFoundException e) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
index 2e9b7b4..c260426 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
@@ -95,7 +95,21 @@
*/
var stagedSessionId = SessionInfo.INVALID_ID
private set
+
+ /**
+ * UID of the last caller of Pia. This can point to a 3P installer if it uses intents to install
+ * an APK, or receives a
+ * [STATUS_PENDING_USER_ACTION][PackageInstaller.STATUS_PENDING_USER_ACTION] status code.
+ * It may point to Pia, when it receives the STATUS_PENDING_USER_ACTION status code in case of
+ * an update-ownership change.
+ */
private var callingUid = Process.INVALID_UID
+
+ /**
+ * UID of the origin of the installation. This UID is used to fetch the app-label of the
+ * source of the install, and also check whether the source app has the AppOp to install other
+ * apps.
+ */
private var originatingUid = Process.INVALID_UID
private var callingPackage: String? = null
private var sessionStager: SessionStager? = null
@@ -135,60 +149,60 @@
stagedSessionId = intent.getIntExtra(EXTRA_STAGED_SESSION_ID, SessionInfo.INVALID_ID)
callingPackage = callerInfo.packageName
-
- if (sessionId != SessionInfo.INVALID_ID) {
- val sessionInfo: SessionInfo? = packageInstaller.getSessionInfo(sessionId)
- callingPackage = sessionInfo?.getInstallerPackageName()
- callingAttributionTag = sessionInfo?.getInstallerAttributionTag()
- }
-
- // Uid of the source package, coming from ActivityManager
callingUid = callerInfo.uid
- if (callingUid == Process.INVALID_UID) {
- Log.e(LOG_TAG, "Could not determine the launching uid.")
- }
+
val sourceInfo: ApplicationInfo? = getSourceInfo(callingPackage)
- // Uid of the source package, with a preference to uid from ApplicationInfo
- originatingUid = sourceInfo?.uid ?: callingUid
- appOpRequestInfo = AppOpRequestInfo(
- getPackageNameForUid(context, originatingUid, callingPackage),
- originatingUid, callingAttributionTag
- )
-
- if(localLogv) {
- Log.i(LOG_TAG, "Intent: $intent\n" +
- "sessionId: $sessionId\n" +
- "staged sessionId: $stagedSessionId\n" +
- "calling package: $callingPackage\n" +
- "callingUid: $callingUid\n" +
- "originatingUid: $originatingUid")
- }
-
if (callingUid == Process.INVALID_UID && sourceInfo == null) {
// Caller's identity could not be determined. Abort the install
Log.e(LOG_TAG, "Cannot determine caller since UID is invalid and sourceInfo is null")
return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
+ originatingUid = callingUid
+ val sessionInfo: SessionInfo? =
+ if (sessionId != SessionInfo.INVALID_ID)
+ packageInstaller.getSessionInfo(sessionId)
+ else null
+ if (sessionInfo != null) {
+ callingAttributionTag = sessionInfo.installerAttributionTag
+ if (sessionInfo.originatingUid != Process.INVALID_UID) {
+ originatingUid = sessionInfo.originatingUid
+ }
+ }
+
+ appOpRequestInfo = AppOpRequestInfo(
+ getPackageNameForUid(context, originatingUid, callingPackage),
+ originatingUid,
+ callingAttributionTag
+ )
+
+ if (localLogv) {
+ Log.i(
+ LOG_TAG, "Intent: $intent\n" +
+ "sessionId: $sessionId\n" +
+ "staged sessionId: $stagedSessionId\n" +
+ "calling package: $callingPackage\n" +
+ "callingUid: $callingUid\n" +
+ "originatingUid: $originatingUid\n" +
+ "sourceInfo: $sourceInfo"
+ )
+ }
+
if ((sessionId != SessionInfo.INVALID_ID
- && !isCallerSessionOwner(packageInstaller, originatingUid, sessionId))
+ && !isCallerSessionOwner(packageInstaller, callingUid, sessionId))
|| (stagedSessionId != SessionInfo.INVALID_ID
&& !isCallerSessionOwner(packageInstaller, Process.myUid(), stagedSessionId))
) {
- Log.e(LOG_TAG, "UID is not the owner of the session:\n" +
- "CallingUid: $originatingUid | SessionId: $sessionId\n" +
- "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId")
+ Log.e(
+ LOG_TAG, "UID is not the owner of the session:\n" +
+ "CallingUid: $callingUid | SessionId: $sessionId\n" +
+ "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId"
+ )
return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
- isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, originatingUid)
- if (!isInstallPermissionGrantedOrRequested(
- context, callingUid, originatingUid, isTrustedSource
- )
- ) {
- Log.e(LOG_TAG, "UID $originatingUid needs to declare " +
- Manifest.permission.REQUEST_INSTALL_PACKAGES
- )
+ isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, callingUid)
+ if (!isInstallPermissionGrantedOrRequested(context, callingUid, isTrustedSource)) {
return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
@@ -196,7 +210,7 @@
if (restriction != null) {
val adminSupportDetailsIntent =
devicePolicyManager!!.createAdminSupportIntent(restriction)
- Log.e(LOG_TAG, "$restriction set in place. Cannot install." )
+ Log.e(LOG_TAG, "$restriction set in place. Cannot install.")
return InstallAborted(
ABORT_REASON_POLICY, message = restriction, resultIntent = adminSupportDetailsIntent
)
@@ -221,12 +235,12 @@
private fun isInstallRequestFromTrustedSource(
sourceInfo: ApplicationInfo?,
intent: Intent,
- originatingUid: Int,
+ callingUid: Int,
): Boolean {
val isNotUnknownSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)
return (sourceInfo != null && sourceInfo.isPrivilegedApp
&& (isNotUnknownSource
- || isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, originatingUid)))
+ || isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, callingUid)))
}
private fun getDevicePolicyRestrictions(): String? {
@@ -311,7 +325,7 @@
Intent.EXTRA_INSTALL_RESULT, PackageManager.INSTALL_FAILED_INVALID_APK
),
activityResultCode = Activity.RESULT_FIRST_USER,
- errorDialogType = if (e is IOException) DLG_PACKAGE_ERROR else DLG_NONE
+ errorDialogType = if (e is IOException) DLG_PACKAGE_ERROR else DLG_NONE
)
return
}
@@ -392,8 +406,9 @@
Log.e(LOG_TAG, "Cannot parse package $debugPathName. Assuming defaults.", e)
params.setSize(pfd.statSize)
} catch (e: IOException) {
- Log.e(LOG_TAG, "Cannot calculate installed size $debugPathName. " +
- "Try only apk size.", e
+ Log.e(
+ LOG_TAG, "Cannot calculate installed size $debugPathName. " +
+ "Try only apk size.", e
)
}
} else {
@@ -651,7 +666,11 @@
private fun getUpdateMessage(pkgInfo: PackageInfo, userActionReason: Int): String? {
if (isAppUpdating(pkgInfo)) {
val existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(pkgInfo)
- val requestedUpdateOwnerLabel = getApplicationLabel(callingPackage)
+
+ val originatingPackageName =
+ getPackageNameForUid(context, originatingUid, callingPackage)
+ val requestedUpdateOwnerLabel = getApplicationLabel(originatingPackageName)
+
if (!TextUtils.isEmpty(existingUpdateOwnerLabel)
&& userActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP
) {
@@ -754,14 +773,14 @@
}
private fun handleUnknownSources(requestInfo: AppOpRequestInfo): InstallStage {
- if (requestInfo.callingPackage == null) {
+ if (requestInfo.originatingPackage == null) {
Log.i(LOG_TAG, "No source found for package " + newPackageInfo?.packageName)
return InstallUserActionRequired(USER_ACTION_REASON_ANONYMOUS_SOURCE)
}
// Shouldn't use static constant directly, see b/65534401.
val appOpStr = AppOpsManager.permissionToOp(Manifest.permission.REQUEST_INSTALL_PACKAGES)
val appOpMode = appOpsManager!!.noteOpNoThrow(
- appOpStr!!, requestInfo.originatingUid, requestInfo.callingPackage,
+ appOpStr!!, requestInfo.originatingUid, requestInfo.originatingPackage,
requestInfo.attributionTag, "Started package installation activity"
)
if (localLogv) {
@@ -772,20 +791,20 @@
AppOpsManager.MODE_DEFAULT, AppOpsManager.MODE_ERRORED -> {
if (appOpMode == AppOpsManager.MODE_DEFAULT) {
appOpsManager.setMode(
- appOpStr, requestInfo.originatingUid, requestInfo.callingPackage,
+ appOpStr, requestInfo.originatingUid, requestInfo.originatingPackage,
AppOpsManager.MODE_ERRORED
)
}
try {
val sourceInfo =
- packageManager.getApplicationInfo(requestInfo.callingPackage, 0)
+ packageManager.getApplicationInfo(requestInfo.originatingPackage, 0)
val sourceAppSnippet = getAppSnippet(context, sourceInfo)
InstallUserActionRequired(
USER_ACTION_REASON_UNKNOWN_SOURCE, appSnippet = sourceAppSnippet,
- dialogMessage = requestInfo.callingPackage
+ sourceApp = requestInfo.originatingPackage
)
} catch (e: PackageManager.NameNotFoundException) {
- Log.e(LOG_TAG, "Did not find appInfo for " + requestInfo.callingPackage)
+ Log.e(LOG_TAG, "Did not find appInfo for " + requestInfo.originatingPackage)
InstallAborted(ABORT_REASON_INTERNAL_ERROR)
}
}
@@ -827,8 +846,10 @@
setStageBasedOnResult(PackageInstaller.STATUS_SUCCESS, -1, null)
} catch (e: PackageManager.NameNotFoundException) {
setStageBasedOnResult(
- PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
- null)
+ PackageInstaller.STATUS_FAILURE,
+ PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
+ null
+ )
}
return
}
@@ -848,7 +869,8 @@
}
} catch (e: OutOfIdsException) {
setStageBasedOnResult(
- PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null)
+ PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null
+ )
return
}
val broadcastIntent = Intent(BROADCAST_ACTION)
@@ -866,7 +888,8 @@
Log.e(LOG_TAG, "Session $stagedSessionId could not be opened.", e)
packageInstaller.abandonSession(stagedSessionId)
setStageBasedOnResult(
- PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null)
+ PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null
+ )
}
}
@@ -876,9 +899,11 @@
message: String?,
) {
if (localLogv) {
- Log.i(LOG_TAG, "Status code: $statusCode\n" +
- "legacy status: $legacyStatus\n" +
- "message: $message")
+ Log.i(
+ LOG_TAG, "Status code: $statusCode\n" +
+ "legacy status: $legacyStatus\n" +
+ "message: $message"
+ )
}
if (statusCode == PackageInstaller.STATUS_SUCCESS) {
val shouldReturnResult = intent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)
@@ -891,11 +916,12 @@
_installResult.setValue(InstallSuccess(appSnippet, shouldReturnResult, resultIntent))
} else {
if (statusCode != PackageInstaller.STATUS_FAILURE_ABORTED) {
- _installResult.setValue(InstallFailed(appSnippet, statusCode, legacyStatus, message))
+ _installResult.setValue(
+ InstallFailed(appSnippet, statusCode, legacyStatus, message)
+ )
} else {
_installResult.setValue(InstallAborted(ABORT_REASON_INTERNAL_ERROR))
}
-
}
}
@@ -939,7 +965,7 @@
data class CallerInfo(val packageName: String?, val uid: Int)
data class AppOpRequestInfo(
- val callingPackage: String?,
+ val originatingPackage: String?,
val originatingUid: Int,
val attributionTag: String?,
)
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
index bbb9bca..5dd4d29 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
@@ -43,7 +43,10 @@
val actionReason: Int,
private val appSnippet: PackageUtil.AppSnippet? = null,
val isAppUpdating: Boolean = false,
- val dialogMessage: String? = null,
+ /**
+ * This holds either a package name or the app label of the install source.
+ */
+ val sourceApp: String? = null,
) : InstallStage(STAGE_USER_ACTION_REQUIRED) {
val appIcon: Drawable?
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
index bae6f68..8572852 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
@@ -128,18 +128,19 @@
/**
* @param context the [Context] object
- * @param callingUid the UID of the caller who's permission is being checked
- * @param originatingUid the UID from where install is being originated. This could be same as
- * callingUid or it will be the UID of the package performing a session based install
- * @param isTrustedSource whether install request is coming from a privileged app or an app that
- * has [Manifest.permission.INSTALL_PACKAGES] permission granted
- * @return `true` if the package is granted the said permission
+ * @param callingUid the UID of the caller of Pia
+ * @param isTrustedSource indicates whether install request is coming from a privileged app
+ * that has passed EXTRA_NOT_UNKNOWN_SOURCE as `true` in the installation intent, or that has
+ * the [INSTALL_PACKAGES][Manifest.permission.INSTALL_PACKAGES] permission granted.
+ *
+ * @return `true` if the package is either a system downloads provider, a document manager,
+ * a trusted source, or has declared the
+ * [REQUEST_INSTALL_PACKAGES][Manifest.permission.REQUEST_INSTALL_PACKAGES] in its manifest.
*/
@JvmStatic
fun isInstallPermissionGrantedOrRequested(
context: Context,
callingUid: Int,
- originatingUid: Int,
isTrustedSource: Boolean,
): Boolean {
val isDocumentsManager =
@@ -148,19 +149,18 @@
getSystemDownloadsProviderInfo(context.packageManager, callingUid) != null
if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager) {
- val targetSdkVersion = getMaxTargetSdkVersionForUid(context, originatingUid)
+ val targetSdkVersion = getMaxTargetSdkVersionForUid(context, callingUid)
if (targetSdkVersion < 0) {
- // Invalid originating uid supplied. Abort install.
- Log.w(LOG_TAG, "Cannot get target sdk version for uid $originatingUid")
+ // Invalid calling uid supplied. Abort install.
+ Log.e(LOG_TAG, "Cannot get target SDK version for uid $callingUid")
return false
} else if (targetSdkVersion >= Build.VERSION_CODES.O
&& !isUidRequestingPermission(
- context.packageManager, originatingUid,
- Manifest.permission.REQUEST_INSTALL_PACKAGES
+ context.packageManager, callingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES
)
) {
Log.e(
- LOG_TAG, "Requesting uid " + originatingUid + " needs to declare permission "
+ LOG_TAG, "Requesting uid " + callingUid + " needs to declare permission "
+ Manifest.permission.REQUEST_INSTALL_PACKAGES
)
return false
@@ -204,13 +204,13 @@
* @return `true` if the caller is the session owner
*/
@JvmStatic
- fun isCallerSessionOwner(pi: PackageInstaller, originatingUid: Int, sessionId: Int): Boolean {
- if (originatingUid == Process.ROOT_UID) {
+ fun isCallerSessionOwner(pi: PackageInstaller, callingUid: Int, sessionId: Int): Boolean {
+ if (callingUid == Process.ROOT_UID) {
return true
}
val sessionInfo = pi.getSessionInfo(sessionId) ?: return false
val installerUid = sessionInfo.getInstallerUid()
- return originatingUid == installerUid
+ return callingUid == installerUid
}
/**
@@ -362,8 +362,8 @@
* @return the packageName corresponding to a UID.
*/
@JvmStatic
- fun getPackageNameForUid(context: Context, sourceUid: Int, callingPackage: String?): String? {
- if (sourceUid == Process.INVALID_UID) {
+ fun getPackageNameForUid(context: Context, uid: Int, preferredPkgName: String?): String? {
+ if (uid == Process.INVALID_UID) {
return null
}
// If the sourceUid belongs to the system downloads provider, we explicitly return the
@@ -371,20 +371,21 @@
// packages, resulting in uncertainty about which package will end up first in the list
// of packages associated with this UID
val pm = context.packageManager
- val systemDownloadProviderInfo = getSystemDownloadsProviderInfo(pm, sourceUid)
+ val systemDownloadProviderInfo = getSystemDownloadsProviderInfo(pm, uid)
if (systemDownloadProviderInfo != null) {
return systemDownloadProviderInfo.packageName
}
- val packagesForUid = pm.getPackagesForUid(sourceUid) ?: return null
+
+ val packagesForUid = pm.getPackagesForUid(uid) ?: return null
if (packagesForUid.size > 1) {
- if (callingPackage != null) {
+ Log.i(LOG_TAG, "Multiple packages found for source uid $uid")
+ if (preferredPkgName != null) {
for (packageName in packagesForUid) {
- if (packageName == callingPackage) {
+ if (packageName == preferredPkgName) {
return packageName
}
}
}
- Log.i(LOG_TAG, "Multiple packages found for source uid $sourceUid")
}
return packagesForUid[0]
}
@@ -439,7 +440,7 @@
*/
data class AppSnippet(var label: CharSequence?, var icon: Drawable?) {
override fun toString(): String {
- return "AppSnippet[label = ${label}, hasIcon = ${icon != null}]"
+ return "AppSnippet[label = $label, hasIcon = ${icon != null}]"
}
}
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
index a95137d..343a213 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
@@ -63,7 +63,7 @@
.setMessage(R.string.untrusted_external_source_warning)
.setPositiveButton(R.string.external_sources_settings,
(dialog, which) -> mInstallActionListener.sendUnknownAppsIntent(
- mDialogData.getDialogMessage()))
+ mDialogData.getSourceApp()))
.setNegativeButton(R.string.cancel,
(dialog, which) -> mInstallActionListener.onNegativeResponse(
mDialogData.getStageCode()))
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
index 99b1eec..e186590 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
@@ -64,7 +64,7 @@
int positiveBtnTextRes;
if (mDialogData.isAppUpdating()) {
- if (mDialogData.getDialogMessage() != null) {
+ if (mDialogData.getSourceApp() != null) {
positiveBtnTextRes = R.string.update_anyway;
} else {
positiveBtnTextRes = R.string.update;
@@ -88,9 +88,10 @@
TextView viewToEnable;
if (mDialogData.isAppUpdating()) {
viewToEnable = dialogView.requireViewById(R.id.install_confirm_question_update);
- String dialogMessage = mDialogData.getDialogMessage();
- if (dialogMessage != null) {
- viewToEnable.setText(Html.fromHtml(dialogMessage, Html.FROM_HTML_MODE_LEGACY));
+ String sourcePackageName = mDialogData.getSourceApp();
+ if (sourcePackageName != null) {
+ // Show the update-ownership change message
+ viewToEnable.setText(Html.fromHtml(sourcePackageName, Html.FROM_HTML_MODE_LEGACY));
}
} else {
viewToEnable = dialogView.requireViewById(R.id.install_confirm_question);
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index 4ac3e67..8666584 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -64,13 +64,6 @@
}
flag {
- name: "allow_all_widgets_on_lockscreen_by_default"
- namespace: "systemui"
- description: "Allow all widgets on the lock screen by default."
- bug: "328261690"
-}
-
-flag {
name: "enable_determining_advanced_details_header_with_metadata"
namespace: "pixel_cross_device_control"
description: "Use metadata instead of device type to determine whether a bluetooth device should use advanced details header."
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 6b6f803..2db6f62 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Laat laai van GPU-ontfoutlae vir ontfoutapps toe"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktiveer woordryke verkoperloginskrywing"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sluit bykomende toestelspesifieke verkoperloglêers by foutverslae in, wat privaat inligting kan bevat, meer batterykrag kan gebruik, en/of meer berging kan gebruik."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Vensteranimasieskaal"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Oorganganimasieskaal"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator-tydsduurskaal"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wekkers en onthounotas"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Laat hierdie app toe om wekkers te stel en tydsensitiewe handelinge te skeduleer. Dit laat die app op die agtergrond werk, wat meer batterykrag kan gebruik.\n\nAs hierdie toestemming af is, sal bestaande wekkers en tydgegronde geleenthede wat deur hierdie app geskeduleer is, nie werk nie."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"skedule, wekker, onthounota, horlosie"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Moenie Steur Nie"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Skakel aan"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Skakel Moenie steur nie aan"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nooit"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Tydsduur"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vra elke keer"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Totdat jy dit afskakel"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Geen naam nie)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Sopas"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Hierdie foon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Hierdie tablet"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 6f494f0..732ec6f 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ለስህተት ማረሚያ መተግበሪያዎች የጂፒዩ ንብርብሮችን መስቀልን ፍቀድ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"የዝርክርክ ቃላት አቅራቢ ምዝግብ ማስታወሻን መያዝ አንቃ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"በሳንካ ሪፖርቶች ውስጥ ተጨማሪ መሣሪያ-ተኮር የአቅራቢ ምዝግብ ማስታወሻዎችን ያካትቱ፣ ይህም የግል መረጃን ሊይዝ፣ ተጨማሪ ባትሪ ሊፈጅ እና/ወይም ተጨማሪ ማከማቻ ሊጠቀም ይችላል።"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"የ Window እነማ ልኬት ለውጥ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"የእነማ ልኬት ለውጥ ሽግግር"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"እነማ አድራጊ ቆይታ መለኪያ"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ማንቂያዎች እና አስታዋሾች"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ይህ መተግበሪያ ማንቂያዎችን እንዲያቀናብር እና የጊዜ ትብነት ያላቸው እርምጃዎችን መርሐግብር እንዲያስይዝ ይፍቀዱለት። ይህ መተግበሪያው ከበስተጀርባ ማሄድ እንዲችል ያስችለዋል፣ ይህም የበለጠ ባትሪ ሊጠቀም ይችላል።\n\nይህ ፈቃድ ከጠፋ በዚህ መተግበሪያ መርሐግብር የተያዘላቸው ነባር ማንቂያዎች እና ጊዜ-ተኮር ክስተቶች አይሰሩም።"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"የጊዜ መርሐግብር፣ ማንቂያ፣ አስታዋሽ ሰዓት"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"አይረብሹ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"አብራ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"አትረብሽን አብራ"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"በጭራሽ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"የቆይታ ጊዜ"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ሁልጊዜ ጠይቅ"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"እስኪያጠፉት ድረስ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ስም የለም)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ልክ አሁን"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ይህ ስልክ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ይህ ጡባዊ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 4b11a76..2964930 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"السماح بتحميل طبقات تصحيح أخطاء GPU لتطبيقات تصحيح الأخطاء"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"تفعيل التسجيل المطوَّل للمورّد"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"تضمين سجلات المورّدين الإضافية الخاصة بالجهاز في تقارير الخطأ، والتي قد تحتوي على معلومات شخصية و/أو تستهلك المزيد من شحن البطارية و/أو تستهلك المزيد من مساحة التخزين"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"حجم الرسوم المتحركة للنافذة"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"حجم الرسوم المتحركة للنقل"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"طول مدة الرسوم المتحركة"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"المنبّهات والتذكيرات"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"يمكنك السماح لهذا التطبيق بضبط المنبّهات وجدولة الإجراءات لتنفيذها في الوقت المناسب. ويسمح هذا الإذن بتشغيل التطبيق في الخلفية، ما قد يستهلك المزيد من البطارية.\n\nفي حال عدم تفعيل هذا الإذن، لن تعمل المنبهات المضبوطة والأحداث المستندة إلى الوقت المجدولة حاليًا في هذا التطبيق."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"جدول زمني، جدولة، منبّه، تذكير، ساعة"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"وضع \"عدم الإزعاج\""</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"تفعيل"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"تفعيل ميزة \"عدم الإزعاج\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"مطلقًا"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"المدة"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"السؤال في كل مرة"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"إلى أن يتم إيقاف الوضع"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(بلا اسم)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"للتو"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"هذا الهاتف"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"هذا الجهاز اللوحي"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index 5a06cb3..b5dfde5 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -71,7 +71,7 @@
<string-array name="bt_hci_snoop_log_profile_filter_entries">
<item msgid="3961868665260627524">"অক্ষম কৰক"</item>
<item msgid="2505973306504851132">"বৰ্ণৰ ষ্ট্ৰীঙেৰে পূৰ কৰক"</item>
- <item msgid="5883011000629613855">"কেৱল হেডাৰ এৰক"</item>
+ <item msgid="5883011000629613855">"কেৱল হে’ডাৰ এৰক"</item>
<item msgid="1051534112762023603">"সম্পূৰ্ণকৈ আঁতৰাওক"</item>
</string-array>
<string-array name="bluetooth_avrcp_versions">
@@ -276,8 +276,8 @@
</string-array>
<string-array name="usb_configuration_titles">
<item msgid="3358668781763928157">"চাৰ্জ কৰি থকা হৈছে"</item>
- <item msgid="7804797564616858506">"এমটিপি (মিডিয়া ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
- <item msgid="910925519184248772">"পিটিপি (পিকচাৰ ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
+ <item msgid="7804797564616858506">"এমটিপি (মিডিয়া ট্ৰান্সফাৰ প্ৰ্ৰ\'টকল)"</item>
+ <item msgid="910925519184248772">"পিটিপি (পিকচাৰ ট্ৰান্সফাৰ প্ৰ্ৰ\'টকল)"</item>
<item msgid="3825132913289380004">"RNDIS (USB ইথাৰনেট)"</item>
<item msgid="8828567335701536560">"ধ্বনিৰ উৎস"</item>
<item msgid="8688681727755534982">"এমআইডিআই"</item>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index d021647..e73462e 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -132,8 +132,8 @@
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ইণ্টাৰনেট সংযোগ শ্বেয়াৰ"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"পাঠ বাৰ্তা"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"ছিমৰ এক্সেছ"</string>
- <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"এইচ্ছডি অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
- <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"এইচ্ছডি অডিঅ’"</string>
+ <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+ <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD অডিঅ’"</string>
<string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"শ্ৰৱণ যন্ত্ৰ"</string>
<string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE অডিঅ’"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="5757754050938807276">"শ্ৰৱণ যন্ত্ৰৰ সৈতে সংযোগ কৰা হৈছে"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ডিবাগ এপসমূহৰ বাবে জিপিইউ ডিবাগ তৰপ ল\'ড কৰিবলৈ অনুমতি দিয়ক"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"বিক্ৰেতাৰ ভাৰ্ব’ছ লগিং সক্ষম কৰক"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"বাগ ৰিপ’ৰ্টসমূহত অতিৰিক্ত ডিভাইচ নিৰ্দিষ্ট বিক্ৰেতাৰ লগসমূহ অন্তৰ্ভুক্ত কৰক, য’ত ব্যক্তিগত তথ্য থাকিব পাৰে, যি অধিক বেটাৰী আৰু/অথবা ষ্ট’ৰেজ ব্যৱহাৰ কৰিব পাৰে।"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"ৱিণ্ড\' এনিমেশ্বন স্কেল"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্ৰাঞ্জিশ্বন এনিমেশ্বন স্কেল"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"এনিমেটৰ কালদৈৰ্ঘ্য স্কেল"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"এলাৰ্ম আৰু ৰিমাইণ্ডাৰ"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"এই এপ্টোক এলাৰ্ম ছেট কৰিবলৈ আৰু সময় সংবেদনশীল কাৰ্যৰ সময়সূচী নিৰ্ধাৰণ কৰিবলৈ দিয়ক। ই এপ্টোক নেপথ্যত চলি থকাৰ অনুমতি দিয়ে যাৰ ফলত অধিক বেটাৰী ব্যৱহাৰ হয়।\n\nএই অনুমতিটো অফ কৰা থাকিলে, ইতিমধ্যে ছেট কৰা এলাৰ্ম আৰু এই এপ্টোৱে সময়সূচী নিৰ্ধাৰণ কৰা সময় ভিত্তিক অনুষ্ঠানসমূহে কাম নকৰা হ’ব।"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"সময়সূচী, এলাৰ্ম, ৰিমাইণ্ডাৰ, ঘড়ী"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"অসুবিধা নিদিব"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"অন কৰক"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"অসুবিধা নিদিব অন কৰক"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"কেতিয়াও নহয়"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"সময়সীমা"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"প্ৰতিবাৰতে সোধক"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"আপুনি অফ নকৰা পর্যন্ত"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(কোনো নাম নাই)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"এই মাত্ৰ"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"এই ফ’নটো"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"এই টেবলেটটো"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b7dda83..2ae6cd3 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Qrafik prosessor qatları sazlanmasının yüklənməsinə icazə verilsin"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Təfsilatlı təchizatçı jurnalı"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xəta hesabatına təchizatçının cihaz haqqında əlavə qeydləri daxil edilsin. Qeydlərdə şəxsi məlumatlar ola, onlar artıq yer tuta və enerji sərfiyyatını artıra bilər."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Pəncərə animasiyası"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Keçid animasiyası"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animasiya müddəti"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Siqnallar və xatırlatmalar"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu tətbiqə siqnallar ayarlamağa və vaxta əsaslanan əməliyyatları planlaşdırmağa icazə verin. Bu, tətbiqin arxa fonda işləməsinə imkan verir ki, nəticədə daha çox enerji istifadə edilə bilər.\n\nBu icazə deaktiv olsa, bu tətbiq tərəfindən planlaşdırılan mövcud siqnallar və vaxta əsaslanan tədbirlər işləməyəcəkdir."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"cədvəl, siqnal, xatırlatma, saat"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Narahat etməyin"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktiv edin"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Narahat Etməyin\" rejimini aktiv edin"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Heç vaxt"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Müddət"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Həmişə soruşulsun"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Deaktiv edilənə qədər"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ad yoxdur)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"İndicə"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Bu telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Bu planşet"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 0e42066..e1e93ef 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Učitava otklanjanje grešaka GPU-a u apl. za otklanjanje grešaka"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Opširne evidencije prodavca"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uvrštava u izveštaje o greškama dodatne posebne evidencije prodavca za uređaje, koje mogu da sadrže privatne podatke, da troše više baterije i/ili da koriste više memorije."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Razmera animacije prozora"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Razmera animacije prelaza"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorova razmera trajanja"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsetnici"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje vremenski osetljive radnje. To omogućava da aplikacija bude pokrenuta u pozadini, što može da troši više baterije.\n\nAko je ova dozvola isključena, postojeći alarmi i događaji zasnovani na vremenu zakazani pomoću ove aplikacije neće raditi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"zakazati, alarm, podsetnik, sat"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne uznemiravaj"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite režim Ne uznemiravaj"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikad"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Dok ne isključite"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez imena)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 95586ea..00eb95d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Загружаць слаі адладкі GPU для праграм адладкі"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Уключыць падрабязны журнал пастаўшчыка"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Дадаваць у справаздачы пра памылкі дадатковыя журналы пастаўшчыка для пэўнай прылады (могуць утрымлівацца прыватныя даныя, можа павышацца выкарыстанне акумулятара і/ці памяці)."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Маштаб анімацыі акна"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Маштаб перадачы анімацыі"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Працягласць анімацыі"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будзільнікі і напаміны"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дазвольце гэтай праграме ўключаць будзільнікі і задаваць час дзеянняў. З такім дазволам праграма можа працаваць у фонавым рэжыме і ў выніку хутчэй разраджаць акумулятар.\n\nКалі вы не ўключыце гэты дазвол, існуючыя будзільнікі і запланаваны праграмай час падзей не будуць працаваць."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"расклад, будзільнік, напамін, гадзіннік"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не турбаваць"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Уключыць"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Уключэнне рэжыму \"Не турбаваць\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ніколі"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Працягласць"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Заўсёды пытацца"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Пакуль не выключыце"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без назвы)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Толькі што"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Гэты тэлефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Гэты планшэт"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 54fef5f..a2db0f9 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Разреш. на зарежд. на слоевете за отстр. на грешки в ГП за съотв. прилож."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Активиране на подробно регистр. на файлове за доставчиците"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включване на допълнителни регистрационни файлове за доставчиците на конкретни устройства в сигналите за програмни грешки, които може да съдържат поверителна информация, да изразходват батерията в по-голяма степен и/или да използват повече място в хранилището."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Скала на прозореца на аним."</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Скала на преходната анимация"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Скала за Animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будилници и напомняния"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Разрешаване на това приложение да задава будилници и да насрочва действия, ограничени във времето. Това му позволява да работи на заден план, при което може да се използва повече батерия.\n\nАко разрешението е изключено, съществуващите будилници и събитията въз основа на времето, насрочени от приложението, няма да работят."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, будилник, напомняне, часовник"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не безпокойте"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включване"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включване на режима „Не безпокойте“"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никога"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Времетраене"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Да се пита винаги"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"До изключване"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Няма име)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Току-що"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Този телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Този таблет"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 1533a19..f8118f4 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ডিবাগ অ্যাপের জন্য GPU ডিবাগ স্তর লোড হতে দিন"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ভারবোস ভেন্ডর লগ-ইন চালু করুন"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"সমস্যা সংক্রান্ত রিপোর্টগুলিতে অতিরিক্ত ডিভাইস-নির্দিষ্ট ভেন্ডরের লগগুলি অন্তর্ভুক্ত করুন, যার মধ্যে ব্যক্তিগত তথ্য থাকতে পারে, আরও বেশি ব্যাটারি ব্যবহার করতে পারে, এবং/অথবা আরও স্টোরেজ ব্যবহার করতে পারে।"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"উইন্ডো অ্যানিমেশন স্কেল"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্র্যানজিশন অ্যানিমেশন স্কেল"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"অ্যানিমেটর সময়কাল স্কেল"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"অ্যালার্ম এবং রিমাইন্ডার"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"অ্যালার্ম এবং সময়ের মধ্যে শেষ করতে হবে এমন অ্যাকশনের শিডিউল সেট করতে এই অ্যাপকে অনুমতি দিন। এর ফলে ব্যাকগ্রাউন্ডে অ্যাপ চলতে পারে, যার জন্য আরও ব্যাটারির চার্জ খরচ হতে পারে।\n\nএই অনুমতি বন্ধ করা থাকলে, আগে থেকে থাকা অ্যালার্ম এবং অ্যাপের মাধ্যমে শিডিউল করা সময় ভিত্তিক ইভেন্টের রিমাইন্ডার কাজ করবে না।"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"শিডিউল, অ্যালার্ম, রিমাইন্ডার, ঘড়ি"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"বিরক্ত করবে না"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"চালু করুন"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'বিরক্ত করবে না\' মোড চালু করুন"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"কখনও নয়"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"সময়কাল"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"প্রতিবার জিজ্ঞেস করা হবে"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"যতক্ষণ না আপনি বন্ধ করছেন"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(কোনও নাম নেই)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"এখনই"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"এই ফোন"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"এই ট্যাবলেট"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 15a9618..2288f05 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Omogućite slojeve za otkl. grešaka na GPU-u za apl. za otkl. grešaka"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogući opširni zapisnik"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"U izvještaje o greškama uključite dodatne zapisnike dobavljača specifične za uređaj, koji mogu sadržavati lične informacije, povećati potrošnju baterije i/ili koristiti više prostora za pohranu."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacije prozora"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacije prijelaza"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala trajanja animatora"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsjetnici"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Dozvolite ovoj aplikaciji da postavlja alarme i zakazuje vremenski osjetljive radnje. Ovim će se omogućiti aplikaciji da radi u pozadini, čime se može povećati potrošnja baterije.\n\nAko je ovo odobrenje isključeno, postojeći alarmi i događaji zasnovani na vremenu, a koje je ova aplikacija zakazala, neće funkcionirati."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne ometaj"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključi način rada Ne ometaj"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikada"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Dok ne isključite"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez imena)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 45f08da..61a6e82 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permet carregar capes de depuració de GPU en aplicacions de depuració"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activa el registre detallat del proveïdor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclou altres registres de proveïdor específics del dispositiu als informes d’errors; és possible que continguin informació privada, consumeixin més bateria o utilitzin més espai d\'emmagatzematge"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala d\'animació de la finestra"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala d\'animació de la transició"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de durada de l\'animació"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes i recordatoris"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permet que aquesta aplicació configuri alarmes i programi accions a una hora determinada. Això permet a l\'aplicació executar-se en segon pla i, per tant, és possible que consumeixi més bateria.\n\nSi aquest permís està desactivat, les alarmes i els esdeveniments que ja hagi programat l\'aplicació no funcionaran."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programació, alarma, recordatori, rellotge"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"No molestis"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activa"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activa el mode No molestis"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mai"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durada"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pregunta sempre"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Fins que no el desactivis"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sense nom)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Ara mateix"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Aquest telèfon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Aquesta tauleta"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 194c616..3444430 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Povolit načítání vrstev ladění GPU pro ladicí aplikace"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Povolit podrobné protokolování dodavatele"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Zahrnovat do zpráv o chybách dodatečné protokoly dodavatelů specifické pro zařízení, které mohou obsahovat soukromé údaje, více vybíjet baterii nebo využívat více místa v úložišti."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Měřítko animace okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Měřítko animace přeměny"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Měřítko délky animace"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Budíky a připomenutí"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Když tuto možnost povolíte, aplikace bude moci nastavovat budíky a plánovat akce závislé na čase. Aplikace poběží na pozadí, což může vést k vyšší spotřebě baterie.\n\nPokud toto oprávnění zůstane vypnuté, stávající budíky a události závislé na čase naplánované touto aplikací nebudou fungovat."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, připomenutí, hodiny"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Nerušit"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnout"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapněte funkci Nerušit"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikdy"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trvání"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pokaždé se zeptat"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Dokud funkci nevypnete"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez jména)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Právě teď"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tento telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tento tablet"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 9e47d6d..1bff907 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillad, at fejlretningslag indlæses for grafikprocessor i apps til fejlretning"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivér detaljeret leverandørlogging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Medtag yderligere enhedsspecifikke leverandørlogfiler i fejlrapporter, som muligvis indeholder personlige oplysninger. Dette bruger muligvis mere batteri og/eller lagerplads."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Animationsskala for vindue"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangsanimationsskala"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorvarighedsskala"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmer og påmindelser"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillad, at denne app indstiller alarmer og planlægger tidsbestemte handlinger. Appen vil køre i baggrunden, hvor den muligvis bruger mere batteri.\n\nHvis denne tilladelse er deaktiveret, vil eksisterende alarmer og tidsbestemte handlinger, der er planlagt af denne app, ikke fungere."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planlæg, alarm, påmindelse, ur"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Forstyr ikke"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivér"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivér Forstyr ikke"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrig"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Varighed"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Spørg hver gang"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Indtil du deaktiverer"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Intet navn)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Lige nu"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Denne telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Denne tablet"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index caeee06..64139a9 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Debug-Apps das Laden von GPU-Debug-Ebenen erlauben"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ausführliche Protokollierung aktivieren"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Schließt zusätzliche gerätespezifische Anbieterprotokolle in Fehlerberichten ein, die private Informationen enthalten, den Akkuverbrauch erhöhen und/oder zusätzlichen Speicher benötigen können."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Fensteranimationsfaktor"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Übergangsanimationsfaktor"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animationsdauerfaktor"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wecker und Erinnerungen"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Dieser App erlauben, Wecker zu stellen und zeitgebundene Aktionen zu planen. Dadurch läuft die App im Hintergrund. Dies kann den Akkuverbrauch erhöhen. \n\nWenn diese Berechtigung deaktiviert ist, funktionieren bereits gestellte Wecker und zeitgebundene Ereignisse, die von dieser App geplant sind, nicht wie erwartet."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planen, Wecker, Erinnerung, Uhr"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Bitte nicht stören"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivieren"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„Bitte nicht stören“ aktivieren"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nie"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Dauer"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Jedes Mal fragen"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Bis zur Deaktivierung"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Kein Name)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Gerade eben"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Dieses Smartphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Dieses Tablet"</string>
@@ -708,7 +722,7 @@
<string name="physical_keyboard_title" msgid="4811935435315835220">"Physische Tastatur"</string>
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Tastaturlayout wählen"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Standard"</string>
- <string name="turn_screen_on_title" msgid="2662312432042116026">"Steuerelement zum Aktivieren des Displays"</string>
+ <string name="turn_screen_on_title" msgid="2662312432042116026">"Berechtigung zum Aktivieren des Displays"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Aktivieren des Displays erlauben"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Einer App erlauben, das Display zu aktivieren. Wenn du diese Erlaubnis erteilst, kann die App jederzeit das Display aktivieren – auch ohne dass du dies beabsichtigst."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 94d4297..f8a6944 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Φόρτωση επιπ. εντοπ. σφ. GPU για εφαρμ. αντιμ. σφ."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ενεργ. λεπτ. καταγραφής προμ."</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Συμπερίληψη πρόσθετων αρχείων καταγραφής προμηθευτή για συγκεκριμένες συσκευές στις αναφορές σφαλμάτων, τα οποία ενδέχεται να περιέχουν ιδιωτικές πληροφορίες, να χρησιμοποιούν περισσότερη μπαταρία ή/και να χρησιμοποιούν περισσότερο αποθηκευτικό χώρο."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Κλίμακα κίνησης παραθύρου"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Κλίμακα κίνησης μετάβασης"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Κλίμ. διάρ. Animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ξυπνητήρια και υπενθυμίσεις"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Επιτρέψτε σε αυτή την εφαρμογή να ορίζει ξυπνητήρια και να προγραμματίζει ενέργειες που εξαρτώνται από τον χρόνο. Αυτό επιτρέπει στην εφαρμογή να εκτελείται στο παρασκήνιο και, ως εκ τούτου, μπορεί να καταναλώνει περισσότερη μπαταρία.\n\nΑν αυτή η άδεια δεν είναι ενεργή, τα υπάρχοντα ξυπνητήρια και συμβάντα βάσει χρόνου που έχουν προγραμματιστεί από αυτή την εφαρμογή δεν θα λειτουργούν."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"πρόγραμμα, ξυπνητήρι, υπενθύμιση, ρολόι"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Μην ενοχλείτε"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ενεργοποίηση"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ενεργοποίηση λειτουργίας \"Μην ενοχλείτε\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ποτέ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Διάρκεια"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Να ερωτώμαι κάθε φορά"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Μέχρι την απενεργοποίηση"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Χωρίς όνομα)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Μόλις τώρα"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Αυτό το τηλέφωνο"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Αυτό το tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index c4d33e0..a6367f1 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 42f9b5f..975cc5e 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -408,6 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery, and/or use more storage."</string>
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Disable after one day"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Verbose vendor logging has ended"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Enabled for one day"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Enable for one more day"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Disables after one day"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Enabled indefinitely"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -557,6 +563,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms & reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +576,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index c4d33e0..a6367f1 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index c4d33e0..a6367f1 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index fd84077..7411487 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -408,6 +408,12 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery, and/or use more storage."</string>
+ <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Disable after one day"</string>
+ <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Verbose vendor logging has ended"</string>
+ <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Enabled for one day"</string>
+ <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Enable for one more day"</string>
+ <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Disables after one day"</string>
+ <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Enabled indefinitely"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -557,6 +563,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms & reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +576,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index b96dd33..3c95fd2 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU para apps de depuración"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Habilitar registro detallado"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluye otros registros de proveedor específicos del dispositivo en los informes de errores, que podrían contener información privada, consumir más batería o usar más espacio de almacenamiento."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación de ventana"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animador"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta app establezca alarmas y programe acciones para horarios específicos. De esta manera, la app puede ejecutarse en segundo plano, lo que podría aumentar el consumo de batería.\n\nSi se desactiva este permiso, no funcionarán las alarmas ni los eventos basados en el tiempo existentes que programe esta app."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"No interrumpir"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar No interrumpir"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar siempre"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que lo desactives"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sin nombre)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Recién"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 0b96faa..28bfb38 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU en aplicaciones de depuración"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Habilitar registro de proveedor detallado"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluye otros registros de proveedor específicos del dispositivo en informes de errores, lo que puede añadir información privada, usar más batería u ocupar más espacio de almacenamiento."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación de ventana"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animación"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones que se llevan a cabo a una hora determinada. Esto hace que la aplicación pueda seguir activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivado, no funcionarán las alarmas ni los eventos que se activan a una hora determinada que programe esta aplicación."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"No molestar"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar el modo No molestar"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar siempre"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que lo desactives"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sin nombre)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"justo ahora"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 42c20399..25bc487 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU silumise kihtide laadimise lubamine silumisrakendustele"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Luba paljusõnaline logimine"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Veaaruannetesse kaasatakse täiendavad seadmepõhised teenusepakkuja logid, mis võivad sisaldada privaatset teavet, kasutada rohkem akut ja/või salvestusruumi."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Akna animatsioonimastaap"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Ülemineku animatsioonimastaap"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaatori kestuse mastaap"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmid ja meeldetuletused"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lubage sellel rakendusel määrata alarme ja ajastada ajakriitilisi toiminguid. See võimaldab rakendusel töötada taustal, mistõttu võib akukasutus olla suurem.\n\nKui see luba on välja lülitatud, siis olemasolevad alarmid ja selle rakenduse ajastatud ajapõhised sündmused ei tööta."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajakava, äratus, meeldetuletus, kell"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Mitte segada"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Lülita sisse"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Valiku Mitte segada sisselülitamine"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mitte kunagi"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Kestus"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Küsi iga kord"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Kuni välja lülitate"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nimi puudub)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Äsja"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"See telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"See tahvelarvuti"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 6376ad5..4b9cb83 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -288,7 +288,7 @@
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM desblokeoa onartu nahi duzu?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"ABISUA: ezarpen hau aktibatuta dagoen bitartean, gailua babesteko eginbideek ez dute gailu honetan funtzionatuko."</string>
<string name="mock_location_app" msgid="6269380172542248304">"Hautatu asmatutako kokapenen aplikazioa"</string>
- <string name="mock_location_app_not_set" msgid="6972032787262831155">"Ez da ezarri kokapen faltsuen aplikaziorik"</string>
+ <string name="mock_location_app_not_set" msgid="6972032787262831155">"Ez da ezarri asmatutako kokapenen aplikaziorik"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"Asmatutako kokapenen aplikazioa: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Sareak"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"Hari gabe bistaratzeko ziurtagiria"</string>
@@ -337,8 +337,8 @@
<string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Hautatu gailuan gordeta utzi nahi dituzun erregistroen bufferrak"</string>
<string name="select_usb_configuration_title" msgid="6339801314922294586">"Hautatu USB konfigurazioa"</string>
<string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Hautatu USB konfigurazioa"</string>
- <string name="allow_mock_location" msgid="2102650981552527884">"Onartu kokapen faltsuak"</string>
- <string name="allow_mock_location_summary" msgid="179780881081354579">"Onartu kokapen faltsuak"</string>
+ <string name="allow_mock_location" msgid="2102650981552527884">"Baimendu asmatutako kokapenak"</string>
+ <string name="allow_mock_location_summary" msgid="179780881081354579">"Baimendu asmatutako kokapenak"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mantendu datu-konexioa beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sare batetik bestera bizkor aldatu ahal izateko)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen bizkortzea"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Eman GPUaren arazketa-geruzak kargatzeko baimena arazketa-aplikazioei"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Gaitu saltzaileen erregistro xehatuak"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sartu gailuaren berariazko saltzaileen erregistro gehigarriak akatsen txostenetan; baliteke haiek informazio pribatua izatea, bateria gehiago erabiltzea eta/edo biltegiratzeko toki gehiago hartzea."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Leihoen animazio-eskala"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Trantsizioen animazio-eskala"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatzailearen iraupen-eskala"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmak eta abisuak"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Eman alarmak ezartzeko eta denbora-muga duten ekintzak programatzeko baimena aplikazioari. Hala, aplikazioak atzeko planoan funtzionatuko du, eta litekeena da bateria gehiago kontsumitzea.\n\nBaimen hori ematen ez baduzu, ez dute funtzionatuko aplikazio honen bidez programatutako alarmek eta denbora-muga duten ekintzek."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programazioa, alarma, abisua, erlojua"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ez molestatzeko modua"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktibatu"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu ez molestatzeko modua"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Inoiz ez"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Iraupena"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Galdetu beti"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Zuk desaktibatu arte"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Izengabea)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Oraintxe"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Telefono hau"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tableta hau"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 6eb8bd1..27e203b 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -64,7 +64,7 @@
<string name="connected_via_network_scorer" msgid="7665725527352893558">"اتصال خودکار ازطریق %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7973529709744526285">"اتصال خودکار ازطریق ارائهدهنده ردهبندی شبکه"</string>
<string name="connected_via_app" msgid="3532267661404276584">"متصل شده ازطریق <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="tap_to_sign_up" msgid="5356397741063740395">"برای ثبتنام ضربه بزنید"</string>
+ <string name="tap_to_sign_up" msgid="5356397741063740395">"برای ثبتنام تکضرب بزنید"</string>
<string name="wifi_connected_no_internet" msgid="5087420713443350646">"عدم اتصال به اینترنت"</string>
<string name="private_dns_broken" msgid="1984159464346556931">"سرور DNS خصوصی قابل دسترسی نیست"</string>
<string name="wifi_limited_connection" msgid="1184778285475204682">"اتصال محدود"</string>
@@ -74,7 +74,7 @@
<string name="osu_opening_provider" msgid="4318105381295178285">"درحال بازکردن <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
<string name="osu_connect_failed" msgid="9107873364807159193">"متصل نشد"</string>
<string name="osu_completing_sign_up" msgid="8412636665040390901">"درحال تکمیل ثبتنام…"</string>
- <string name="osu_sign_up_failed" msgid="5605453599586001793">"ثبتنام تکمیل نشد. برای امتحان مجدد ضربه بزنید."</string>
+ <string name="osu_sign_up_failed" msgid="5605453599586001793">"ثبتنام تکمیل نشد. برای امتحان مجدد تکضرب بزنید."</string>
<string name="osu_sign_up_complete" msgid="7640183358878916847">"ثبتنام کامل شد. درحال اتصال…"</string>
<string name="speed_label_slow" msgid="6069917670665664161">"آهسته"</string>
<string name="speed_label_okay" msgid="1253594383880810424">"تأیید"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"مجاز کردن بارگیری لایههای اشکالزدایی GPU برای برنامههای اشکالزدایی"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"فعال کردن گزارشگیری مفصل فروشنده"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"شامل گزارشات اشکال تکمیلی ورود به سیستم فروشنده ویژه دستگاه میشود که ممکن است دربرگیرنده اطلاعات خصوصی، استفاده بیشتر از باتری، و/یا استفاده بیشتر از فضای ذخیرهسازی باشد."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"مقیاس پویانمایی پنجره"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"مقیاس پویانمایی انتقالی"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"مقیاس طول مدت انیماتور"</string>
@@ -428,7 +440,7 @@
<string name="enable_freeform_support_summary" msgid="1822862728719276331">"فعال کردن پشتیبانی برای پنجرههای آزاد آزمایشی."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"گذرواژه پشتیبانگیری محلی"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"پشتیبانگیری کامل رایانه درحال حاضر محافظت نمیشود"</string>
- <string name="local_backup_password_summary_change" msgid="1707357670383995567">"برای تغییر یا حذف گذرواژه برای نسخههای پشتیبان کامل رایانهای ضربه بزنید"</string>
+ <string name="local_backup_password_summary_change" msgid="1707357670383995567">"برای تغییر یا حذف گذرواژه برای نسخههای پشتیبان کامل رایانهای تکضرب بزنید"</string>
<string name="local_backup_password_toast_success" msgid="4891666204428091604">"گذرواژه جدید نسخهٔ پشتیبان تنظیم شد"</string>
<string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"گذرواژه جدید و تأیید آن با یکدیگر مطابقت ندارند"</string>
<string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"گذرواژه پشتیبانگیری تنظیم نشد"</string>
@@ -444,8 +456,8 @@
<item msgid="1282170165150762976">"رنگهای بهینهشده برای محتوای دیجیتالی"</item>
</string-array>
<string name="inactive_apps_title" msgid="5372523625297212320">"برنامههای آماده بهکار"</string>
- <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"غیرفعال. برای تغییر حالت ضربه بزنید."</string>
- <string name="inactive_app_active_summary" msgid="8047630990208722344">"فعال. برای تغییر حالت ضربه بزنید."</string>
+ <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"غیرفعال. برای تغییر حالت تکضرب بزنید."</string>
+ <string name="inactive_app_active_summary" msgid="8047630990208722344">"فعال. برای تغییر حالت تکضرب بزنید."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"وضعیت حالت آماده بهکار برنامه:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="transcode_settings_title" msgid="2581975870429850549">"تنظیمات تراتبدیل رسانه"</string>
<string name="transcode_user_control" msgid="6176368544817731314">"ملغی کردن پیشفرضهای تراتبدیل"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"زنگهای ساعت و یادآوریها"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"به این برنامه اجازه میدهد زنگ ساعت تنظیم کند و کنشهای حساس به زمان را زمانبندی کند. این تنظیم به برنامه اجازه میدهد در پسزمینه اجرا شود که ممکن است باتری بیشتری مصرف کند.\n\nاگر این اجازه خاموش باشد، زنگهای ساعت موجود و رویدادهای زمانمحور که این برنامه زمانبندی کرده است کار نخواهند کرد."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"زمانبندی، زنگ ساعت، یادآوری، ساعت"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"مزاحم نشوید"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"روشن کردن"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"روشن کردن «مزاحم نشوید»"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"هرگز"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"مدت"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"هربار پرسیده شود"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"تا زمانیکه آن را خاموش کنید"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(بدون نام)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"هماکنون"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"این تلفن"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"این رایانه لوحی"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index a0dc830..a8222b9 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Salli GPU:n virheenkorjauskerrosten lataus"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Käytä laajennettua kirjausta"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sisällytä virheraportteihin muita laitekohtaisia myyjälokeja, jotka voivat sisältää yksityisiä tietoja, käyttää enemmän akkua ja/tai käyttää enemmän tallennustilaa"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Ikkuna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Siirtymä"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaattori"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Herätykset ja muistutukset"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Anna sovelluksen lisätä herätyksiä ja ajoittaa kiireellisiä tapahtumia. Näin sovellus voi toimia taustalla, mikä voi kuluttaa enemmän virtaa.\n\nIlman tätä lupaa sovelluksen ajoittamat herätykset ja aikaan perustuvat tapahtumat eivät toimi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajoitus, herätys, muistutus, kello"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Älä häiritse"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ota käyttöön"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Laita Älä häiritse ‑tila päälle"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ei koskaan"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Kesto"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Kysy aina"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Kunnes laitat pois päältä"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ei nimeä)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Äsken"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tämä puhelin"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tämä tabletti"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 0e03d18..cdc1e44 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Autoriser couches débogage GPU pour applis de débogage"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activer le journal détaillé des fournisseurs"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluez les journaux supplémentaires du fournisseur propres à l\'appareil dans les rapports de bogue. Ils peuvent contenir des données personnelles, épuiser la pile plus rapidement et/ou utiliser plus d\'espace de stockage."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Échelle animation fenêtres"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Éch. d\'animation des transitions"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle durée animation"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette application à créer des alarmes et à programmer des actions urgentes. Cela permet à l’application de s\'exécuter en arrière-plan, ce qui peut nécessiter plus de pile.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements en temps réel programmés par cette application ne fonctionneront pas."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"horaire, alarme, rappel, horloge"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne pas déranger"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durée"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Toujours demander"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Jusqu\'à la désactivation"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sans nom)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"À l\'instant"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ce téléphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Cette tablette"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ed4bf48..300dca1 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Autoriser le chargement de couches de débogage GPU"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activer la journalisation détaillée du fournisseur"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclure les journaux supplémentaires du fournisseur, spécifiques à l\'appareil, dans les rapports de bug. Ils peuvent contenir des informations personnelles, solliciter davantage la batterie et/ou utiliser plus d\'espace de stockage."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Échelle d\'animation des fenêtres"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Échelle d\'animation des transitions"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle de durée d\'animation"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autoriser cette appli à définir des alarmes et à programmer des actions à certaines heures. Elle s\'exécutera alors en arrière-plan, ce qui peut solliciter davantage la batterie.\n\nSi l\'autorisation est désactivée, les alarmes existantes et les événements programmés par l\'appli ne fonctionneront pas."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"définir, alarme, rappel, horloge"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne pas déranger"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durée"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Toujours demander"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Jusqu\'à ce que vous le désactiviez"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sans nom)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"À l\'instant"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ce téléphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Cette tablette"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 3a08d2f..d00d6d3 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración da GPU para aplicacións de depuración"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activar rexistro de provedores"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclúe outros rexistros de provedores específicos do dispositivo en informes de erros; pode conter información privada, consumir máis batería e ocupar máis espazo de almacenamento"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación da ventá"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala animación-transición"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala duración animador"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas e recordatorios"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación defina alarmas e planifique accións que dependan da hora. Con este permiso, a aplicación pode executarse en segundo plano, o que pode provocar un maior consumo de batería.\n\nSe este permiso está desactivado, non funcionarán as alarmas que xa se definisen nin os eventos que dependan da hora planificados por esta aplicación."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planificar, alarma, recordatorio, reloxo"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Non molestar"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar modo Non molestar"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar sempre"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Ata a desactivación"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sen nome)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tableta"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 07eda9a..0c204f7 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ડિબગ ઍપ માટે GPU ડિબગ સ્તરો લોડ કરવાની મંજૂરી આપો"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"વર્બોઝ વેન્ડર લૉગિંગ ચાલુ કરો"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ખામીની જાણકારીમાં ડિવાઇસથી જોડાયેલા ચોક્કસ વેન્ડર લૉગ શામેલ કરો, જેમાં ખાનગી માહિતી શામેલ હોઈ શકે છે, તે વધુ બૅટરીનો ઉપયોગ કરી શકે છે અને/અથવા વધુ સ્ટોરેજનો ઉપયોગ કરી શકે છે."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"વિન્ડો ઍનિમેશન સ્કેલ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ટ્રાન્ઝિશન ઍનિમેશન સ્કેલ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ઍનિમેટર અવધિ સ્કેલ"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"અલાર્મ અને રિમાઇન્ડર"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"આ ઍપને અલાર્મ સેટ કરવા અને સમય પ્રતિ સંવેદનશીલ ક્રિયાઓ શેડ્યૂલ કરવા માટે મંજૂરી આપો. આ ઍપને બૅકગ્રાઉન્ડમાં ચાલવા દે છે, જેને કારણે બૅટરીનો વધુ વપરાશ થઈ શકે છે.\n\nજો આ પરવાનગી બંધ હોય, તો આ ઍપ દ્વારા શેડ્યૂલ કરવામાં આવેલા વર્તમાન અલાર્મ અને સમય આધારિત ઇવેન્ટ કામ કરશે નહીં."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"શેડ્યૂલ, અલાર્મ, રિમાઇન્ડર, ઘડિયાળ"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ખલેલ પાડશો નહીં"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ચાલુ કરો"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ખલેલ પાડશો નહીં ચાલુ કરો"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ક્યારેય નહીં"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"અવધિ"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"દર વખતે પૂછો"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"તમે બંધ ન કરો ત્યાં સુધી"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(નામ નથી)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"હમણાં જ"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"આ ફોન"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"આ ટૅબ્લેટ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 7db157e..2c938a6 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डीबग ऐप के लिए जीपीयू डीबग लेयर लोड करने दें"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"वर्बोस वेंडर लॉगिंग चालू करें"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"गड़बड़ियों की रिपोर्ट में डिवाइस से जुड़े अतिरिक्त वेंडर लॉग शामिल करें. इन लॉग में निजी जानकारी, बैटरी का ज़्यादा इस्तेमाल, और/या डिवाइस का स्टोरेज ज़्यादा इस्तेमाल करने की जानकारी हो सकती है."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"विंडो ऐनिमेशन स्केल"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांज़िशन ऐनिमेशन स्केल"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ऐनिमेटर ड्यूरेशन स्केल"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म और रिमाइंडर"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे बैटरी ज़्यादा खर्च होती है.\n\nऐप्लिकेशन को यह अनुमति न देने पर, इसकी मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्यूल, अलार्म, रिमाइंडर, घड़ी"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"परेशान न करें"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करें"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'परेशान न करें\' चालू करें"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कभी नहीं"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"अवधि"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"हर बार पूछें"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"जब तक इसे बंद नहीं किया जाता"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(कोई नाम नहीं)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"अभी-अभी"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"यह फ़ोन"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यह टैबलेट"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ef0d589..260e9c2 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Omogućuje učitavanje slojeva za otklanjanje pogrešaka GPU-a za aplikacije za otklanjanje pogrešaka"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogući opširni zapisnik"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uključite dodatne zapisnike dobavljača pojedinog uređaja u izvješća o programskim pogreškama koja mogu sadržavati privatne podatke, trošiti više baterije i/ili zauzeti više prostora za pohranu."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Brzina animacije prozora"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Brzina animacije prijelaza"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Razmjer duljine animatora"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsjetnici"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite toj aplikaciji da postavlja alarme i zakazuje radnje u točno određeno vrijeme. To aplikaciji omogućuje da se izvodi u pozadini, pa je moguća dodatna potrošnja baterije.\n\nAko je to dopuštenje isključeno, postojeći alarmi i događaji zakazani putem te aplikacije neće funkcionirati."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne uznemiravaj"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite opciju Ne uznemiravaj."</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikada"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Do isključivanja"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez imena)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Upravo sad"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index fb142f6..b16f4a3 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU-hibakeresési rétegek betöltésének engedélyezése"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Részletes szolgáltatói naplózás engedélyezése"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"További eszközspecifikus szolgáltatói naplók felvétele a hibajelentésekbe. Ezek a naplók tartalmazhatnak privát információkat, ezenkívül előfordulhat, hogy jobban merítik az akkumulátort, illetve nagyobb tárhelyet foglalnak el."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Ablakanimáció tempója"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Áttűnési animáció tempója"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animáció tempója"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ébresztések és emlékeztetők"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lehetővé teszi ennek az alkalmazásnak, hogy ébresztéseket állítson be és időérzékeny feladatokat ütemezzen. Ezzel engedélyezi az alkalmazásnak, hogy a háttérben fusson, ami megnövekedett akkumulátorhasználattal járhat.\n\nHa ez az engedély ki van kapcsolva, az alkalmazás által beállított ébresztések és ütemezett időérzékeny események nem fognak működni."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ütemezés, ébresztés, emlékeztető, óra"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne zavarjanak"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bekapcsolás"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"A Ne zavarjanak mód bekapcsolása"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Soha"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Időtartam"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Mindig kérdezzen rá"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Kikapcsolásig"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nincs név)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Az imént"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ez a telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ez a táblagép"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index e7cbf2d..bd9e564 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -237,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"Ընտրեք պրոֆիլ"</string>
<string name="category_personal" msgid="6236798763159385225">"Անձնական"</string>
<string name="category_work" msgid="4014193632325996115">"Աշխատանքային"</string>
- <string name="category_private" msgid="4244892185452788977">"Անձնական"</string>
+ <string name="category_private" msgid="4244892185452788977">"Մասնավոր"</string>
<string name="category_clone" msgid="1554511758987195974">"Կլոն"</string>
<string name="development_settings_title" msgid="140296922921597393">"Մշակողի ընտրանքներ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Միացնել մշակողի ընտրանքները"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Թույլատրել GPU վրիպազերծման շերտերի բեռնումը վրիպազերծման հավելվածների համար"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Մատակարարի մանրամասն գրանցամատյան"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Վրիպակների հաշվետվություններում ներառել կոնկրետ սարքի վերաբերյալ մատակարարի լրացուցիչ մատյանները։ Դա կարող է պարունակել խիստ անձնական տեղեկություններ, ավելի արագ սպառել մարտկոցի լիցքը և/կամ ավելի շատ տարածք օգտագործել։"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Պատուհանի շարժապատկեր"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Անցումների շարժապատկեր"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Շարժանկարի տևողության սանդղակ"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Զարթուցիչներ և հիշեցումներ"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Թույլատրել այս հավելվածին զարթուցիչներ կարգավորել և որոշակի ժամանակի համար գործողություններ պլանավորել։ Այդ դեպքում հավելվածն աշխատում է ֆոնային ռեժիմում, և արդյունքում մարտկոցի լիցքն ավելի արագ է սպառվում։\n\nԵթե այս թույլտվությունն անջատված է, հավելվածի կողմից կարգավորված զարթուցիչները և գործողությունների ժամանակացույցները չեն աշխատի։"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ժամանակացույց, զարթուցիչ, հիշեցում, ժամացույց"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Չանհանգստացնել"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Միացնել"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Միացրեք «Չանհանգստացնել» ռեժիմը"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Երբեք"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Տևողություն"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ամեն անգամ հարցնել"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Մինչև անջատեք"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Անանուն)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Հենց նոր"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Այս հեռախոսը"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Այս պլանշետը"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 82a390e..b3a1291 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Izinkan lapisan debug GPU dimuat di aplikasi debug"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktifkan logging vendor panjang"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sertakan log vendor tambahan khusus perangkat dalam laporan bug, yang mungkin berisi informasi pribadi. Meningkatkan penggunaan baterai dan/atau ruang penyimpanan."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animasi jendela"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi transisi"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala durasi animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarm & pengingat"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Mengizinkan aplikasi ini menyetel alarm dan menjadwalkan tindakan yang sensitif waktu. Hal ini memungkinkan aplikasi berjalan di latar belakang, sehingga mungkin menggunakan lebih banyak daya baterai.\n\nJika izin ini dinonaktifkan, alarm dan acara berbasis waktu yang dijadwalkan oleh aplikasi ini tidak akan berfungsi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadwal, alarm, pengingat, jam"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Jangan Ganggu"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktifkan"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktifkan mode Jangan Ganggu"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Tidak pernah"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durasi"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Selalu tanya"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Sampai Anda menonaktifkannya"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Tanpa nama)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Baru saja"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ponsel ini"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tablet ini"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 47cdcca..7712b8a 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Leyfa villuleit skjákorts fyrir villuleit forrita"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Nákvæm skráning söluaðila"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Taka með viðbótarannála söluaðila fyrir tiltekin tæki í villutilkynningum, sem gætu innihaldið viðkvæmar upplýsingar, notað meiri rafhlöðuorku og/eða þurft meira geymslupláss."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Kvarði gluggahreyfinga"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Lengd hreyfiumbreytinga"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Tímalengd hreyfiáhrifa"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Vekjarar og áminningar"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Leyfa þessu forriti að stilla vekjara og áætla aðgerðir sem þurfa að eiga sér stað innan ákveðins tímaramma. Þetta leyfir forritinu að keyra í bakgrunninum sem getur notað meiri rafhlöðuorku.\n\nEf slökkt er á þessari heimild munu núverandi vekjarar og tímasettir viðburðir sem þetta forrit stillir ekki virka."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"áætlun, vekjari, áminning, klukka"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ónáðið ekki"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Kveikja"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Kveikja á „Ónáðið ekki“"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrei"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Lengd"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Spyrja í hvert skipti"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Þar til þú slekkur"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nafn vantar)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Rétt í þessu"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Þessi sími"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Þessi spjaldtölva"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 3714593..a661700 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Consenti caricamento livelli debug GPU per app di debug"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Attiva log dettagliati fornitori"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Includi log aggiuntivi di fornitori relativi a un dispositivo specifico nelle segnalazioni di bug che potrebbero contenere informazioni private, causare un maggior consumo della batteria e/o utilizzare più spazio di archiviazione"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Scala animazione finestra"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Scala animazione transizione"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Scala durata animatore"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Sveglie e promemoria"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Consenti a questa app di impostare sveglie e programmare azioni per orari specifici. L\'app potrà essere eseguita in background, comportando un consumo maggiore della batteria.\n\nSe questa autorizzazione viene disattivata, le sveglie esistenti e gli eventi basati sull\'orario programmati da questa app non funzioneranno."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programmare, sveglia, promemoria, orologio"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Non disturbare"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Attiva"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Attiva Non disturbare"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mai"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durata"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Chiedi ogni volta"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Fino alla disattivazione"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nessun nome)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Adesso"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Questo smartphone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Questo tablet"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index c2f4a8f..fe674bc 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -125,7 +125,7 @@
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"אודיו של מדיה"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"שיחות טלפון"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"העברת קבצים"</string>
- <string name="bluetooth_profile_hid" msgid="2969922922664315866">"התקן קלט"</string>
+ <string name="bluetooth_profile_hid" msgid="2969922922664315866">"מכשיר לקליטת נתונים"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"גישה לאינטרנט"</string>
<string name="bluetooth_profile_pbap" msgid="2103406516858653017">"אישור גישה אל אנשי הקשר והיסטוריית השיחות"</string>
<string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"המידע הזה ישמש למשל כדי להשמיע התראות על שיחות נכנסות"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"טעינת שכבות לניפוי באגים ב-GPU לאפליקציות ניפוי באגים"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"הפעלת רישום ספקים מפורט ביומן"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"הוספת רישומי יומן של יצרנים למכשירים ספציפיים בדוחות על באגים. דוחות אלה עשויים להכיל מידע פרטי, להגביר את צריכת הסוללה ולצרוך נפח אחסון גדול יותר."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"קנה מידה לאנימציה של חלון"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"קנה מידה לאנימציית מעבר"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"קנה מידה למשך זמן אנימציה"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"שעונים מעוררים ותזכורות"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ההרשאה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות דחופות. האפליקציה תוכל לפעול ברקע ובכך להגביר את צריכת הסוללה.\n\nאם ההרשאה מושבתת, ההתראות והאירועים מבוססי-הזמן שהוגדרו ותוזמנו על ידי האפליקציה לא יפעלו."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"תזמון, שעון מעורר, תזכורת, שעון"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"נא לא להפריע"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"הפעלה"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"הפעלת מצב נא לא להפריע"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"אף פעם"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"משך זמן"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"יש לשאול בכל פעם"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"עד הכיבוי"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ללא שם)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"הרגע"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"הטלפון הזה"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"הטאבלט הזה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 17e902e..f5ee5c4 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"デバッグアプリに GPU デバッグレイヤの読み込みを許可"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ベンダーの詳細なロギングを有効にする"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"バグレポートには、その他のデバイス固有のベンダーログが含まれます。これには、非公開の情報が含まれることがあります。また、バッテリーやストレージの使用量が増えることもあります。"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"ウィンドウ アニメ スケール"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"トランジション アニメ スケール"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 再生時間スケール"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"アラームとリマインダー"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"アラームの設定や時間ベースのアクション設定を、このアプリに許可します。これによりアプリがバックグラウンドで実行できるようになるため、バッテリーの使用量が増えることがあります。\n\nこの権限が OFF の場合、このアプリで設定された既存のアラームと時間ベースのイベントは機能しなくなります。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"スケジュール, アラーム, リマインダー, 時計"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"サイレント モード"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ON にする"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"サイレント モードを ON にする"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"なし"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"時間"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"毎回確認"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"OFF にするまで"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(名前なし)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"たった今"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"このデバイス"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"このタブレット"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 4efebc5..1c5822c 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -412,6 +412,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"გასამართი აპებისთვის GPU-ს შეცდომების გამართვის შრეების გაშვების დაშვება"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ჟურნალებში მომწოდებელთა დაწვრილებითი აღრიცხვის ჩართვა"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"გამყიდველის მოწყობილობისთვის სპეციფიკური დამატებითი ჟურნალები შევიდეს სისტემის ხარვეზის ანგარიშებში, რომლებიც შეიძლება შეიცავდეს პირად ინფორმაციას, ხარჯავდეს ბატარეის მეტ მუხტს და/ან იყენებდეს მეტ მეხსიერებას."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"ფანჯარა: მასშტაბი"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"გადასვლის მასშტაბი"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ანიმაციების ხანგრძლივობის მასშტაბი"</string>
@@ -561,6 +573,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"მაღვიძარები და შეხსენებები"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ნებას რთავს ამ აპს, დააყენოს მაღვიძარები და დაგეგმოს დროზე დამოკიდებული მოქმედებები. ეს საშუალებას აძლევს აპს, იმუშაოს ფონურად, რამაც შეიძლება ბატარეის ხარჯი გაზარდოს.\n\nთუ ეს ნებართვა გამორთულია, ამ აპით დაგეგმილი მაღვიძარები და დროზე დამოკიდებული მოვლენები არ იმუშავებს."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"განრიგი, მაღვიძარა, შეხსენება, საათი"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"არ შემაწუხოთ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ჩართვა"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„არ შემაწუხოთ“ რეჟიმის ჩართვა"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"არასოდეს"</string>
@@ -573,6 +586,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ხანგრძლივობა"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ყოველთვის მკითხეთ"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"გამორთვამდე"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(უსახელო)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ახლახან"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ეს ტელეფონი"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ამ ტაბლეტზე"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index a1ea070..ef9b005 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -58,7 +58,7 @@
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" қолданбасына қосылу мүмкін емес"</string>
<string name="wifi_check_password_try_again" msgid="8817789642851605628">"Құпия сөзді тексеріп, әрекетті қайталаңыз"</string>
<string name="wifi_not_in_range" msgid="1541760821805777772">"Аумақта жоқ"</string>
- <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматты қосылмайды"</string>
+ <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматты түрде қосылмайды"</string>
<string name="wifi_no_internet" msgid="1774198889176926299">"Интернетпен байланыс жоқ"</string>
<string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> сақтаған"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s арқылы автоматты қосылды"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU түзету қабаттарының жүктелуіне рұқсат ету"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Жеткізуші туралы толық мәліметті тіркеу"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Қате туралы есепте жеткізушінің құрылғыға қатысты қосымша ақпараты қамтылады. Мұнда жеке ақпарат көрсетілуі, батарея шығыны артуы және/немесе қосымша жад пайдаланылуы мүмкін."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Терезе анимациясының өлшемі"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Ауысу анимациясының өлшемі"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматор ұзақтығы"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Оятқыштар мен еске салғыштар"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бұл қолданбаға оятқыштарды орнатуға және уақытқа байланысты әрекеттерді жоспарлауға рұқсат береді. Мұндайда қолданба фондық режимде жұмыс істейді, сондықтан батарея шығыны артуы мүмкін.\n\nБұл рұқсат өшірулі болса, осы қолданбада жоспарланған ағымдағы оятқыштар мен уақытқа байланысты іс-шаралар жұмыс істемейді."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"кесте, оятқыш, еске салғыш, сағат"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Мазаламау"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Қосу"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Мазаламау режимін қосу"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ешқашан"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Ұзақтығы"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Әрдайым сұрау"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Өшірілгенге дейін"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Аты берілмеген)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Дәл қазір"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Осы телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Осы планшет"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 431bdf7..199b114 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"អនុញ្ញាតឱ្យផ្ទុកស្រទាប់ជួសជុល GPU សម្រាប់កម្មវិធីជួសជុល"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"បើកការកត់ត្រាអ្នកផ្គត់ផ្គង់ឥតសំចៃ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"រួមបញ្ចូលកំណត់ហេតុអ្នកផ្គត់ផ្គង់ពាក់ព័ន្ធនឹងឧបករណ៍បន្ថែមទៀតនៅក្នុងរបាយការណ៍អំពីបញ្ហា ដែលអាចមានផ្ទុកព័ត៌មានឯកជន ប្រើប្រាស់ថ្មច្រើនជាង និង/ឬប្រើប្រាស់ទំហំផ្ទុកច្រើនជាង។"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"មាត្រដ្ឋានចលនាវិនដូ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"មាត្រដ្ឋានដំណើរផ្លាស់ប្ដូរចលនា"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"មាត្រដ្ឋានរយៈពេលនៃកម្មវិធីចលនា"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ម៉ោងរោទ៍ និងការរំលឹក"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យកម្មវិធីនេះកំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ ការធ្វើបែបនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មកាន់តែច្រើន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកំណត់ដោយកម្មវិធីនេះនឹងមិនដំណើរការទេ។"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"កាលវិភាគ ម៉ោងរោទ៍ ការរំលឹក នាឡិកា"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"កុំរំខាន"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"បើក"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"បើកមុខងារកុំរំខាន"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"កុំឱ្យសោះ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"រយៈពេល"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"សួរគ្រប់ពេល"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"រហូតទាល់តែអ្នកបិទ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(គ្មានឈ្មោះ)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"អម្បាញ់មិញ"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ទូរសព្ទនេះ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ថេប្លេតនេះ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a25e179..6ff80d8 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ಡೀಬಗ್ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ GPU ಡೀಬಗ್ ಲೇಯರ್ಗಳನ್ನು ಲೋಡ್ ಮಾಡುವುದನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ವರ್ಬೋಸ್ ವೆಂಡರ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ಬಗ್ ವರದಿಗಳಲ್ಲಿ ಹೆಚ್ಚುವರಿ ಸಾಧನ ನಿರ್ದಿಷ್ಟ ವೆಂಡರ್ ಲಾಗ್ಗಳು ಒಳಗೊಂಡಿದೆ, ಇದು ಖಾಸಗಿ ಮಾಹಿತಿ, ಹೆಚ್ಚಿನ ಬ್ಯಾಟರಿ ಬಳಕೆ ಮತ್ತು/ಅಥವಾ ಹೆಚ್ಚಿನ ಸಂಗ್ರಹಣೆಯ ಬಳಕೆಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Window ಅನಿಮೇಶನ್ ಸ್ಕೇಲ್"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ಪರಿವರ್ತನೆ ಅನಿಮೇಶನ್ ಸ್ಕೇಲ್"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ಅನಿಮೇಟರ್ ಅವಧಿಯ ಪ್ರಮಾಣ"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ಅಲಾರಂಗಳು ಮತ್ತು ರಿಮೈಂಡರ್ಗಳು"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ಅಲಾರಂಗಳನ್ನು ಹೊಂದಿಸಲು ಮತ್ತು ಸಮಯ-ಸೂಕ್ಷ್ಮವಾದ ಕ್ರಿಯೆಗಳನ್ನು ನಿಗದಿಪಡಿಸಲು ಈ ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸಿ. ಇದು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ, ಅದರಿಂದ ಹೆಚ್ಚು ಬ್ಯಾಟರಿ ಬಳಕೆಯಾಗಬಹುದು.\n\nಈ ಅನುಮತಿ ಆಫ್ ಆಗಿದ್ದರೆ, ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅಲಾರಂಗಳು ಮತ್ತು ಈ ಆ್ಯಪ್ ನಿಗದಿಪಡಿಸಿದ ಸಮಯ-ಸೂಕ್ಷ್ಮ ಈವೆಂಟ್ಗಳು ಕೆಲಸ ಮಾಡುವುದಿಲ್ಲ."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ವೇಳಾಪಟ್ಟಿ, ಅಲಾರಂ, ರಿಮೈಂಡರ್, ಗಡಿಯಾರ"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ಆನ್ ಮಾಡಿ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ಎಂದೂ ಇಲ್ಲ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ಅವಧಿ"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ಪ್ರತಿ ಬಾರಿ ಕೇಳಿ"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"ನೀವು ಆಫ್ ಮಾಡುವವರೆಗೆ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ಯಾವುದೇ ಹೆಸರಿಲ್ಲ)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ಇದೀಗ"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ಈ ಫೋನ್"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ಈ ಟ್ಯಾಬ್ಲೆಟ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 9cb770f..af5f9d4 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"디버그 앱에 GPU 디버그 레이어 로드 허용"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"상세 공급업체 로깅 사용 설정"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"버그 신고에 추가적인 기기별 공급업체 로그를 포함합니다. 여기에는 개인정보가 포함될 수 있으며, 배터리 또는 저장공간 사용량이 늘어날 수 있습니다."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"창 애니메이션 배율"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"전환 애니메이션 배율"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 길이 배율"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"알람 및 리마인더"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"이 앱이 알람을 설정하고 시간 기반 작업을 예약할 수 있도록 허용합니다. 이렇게 하면 백그라운드에서 앱 실행이 허용되어 배터리 사용량이 증가할 수 있습니다.\n\n이 권한을 사용 중지하면 이 앱에서 예약한 기존의 알람 및 시간 기반 일정이 작동하지 않습니다."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"일정 예약, 알람, 리마인더, 시계"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"방해 금지 모드"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"사용 설정"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"방해 금지 모드 사용 설정"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"사용 안함"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"지속 시간"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"항상 확인"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"사용 중지할 때까지"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(이름 없음)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"조금 전"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"이 휴대전화"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"이 태블릿"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 64180a9..1d3f44a 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU мүчүлүштүктөрдү оңдоо катмарларын иштетет"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Кызмат көрсөтүүчүнүн журналы"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Кызмат көрсөтүүчүнүн түзмөккө байланыштуу кошумча жазуулары мүчүлүштүк тууралуу кабарларга кошулат. Анда купуя маалымат камтылып, батарея тезирээк отуруп жана/же сактагычтан көбүрөөк орун ээлеши мүмкүн."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Терезелердин анимациясы"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Өткөрүү анимацснн шкаласы"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимациянын узактыгы"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ойготкучтар жана эстеткичтер"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат бересиз. Ушуну менен колдонмо фондо иштеп, батареяны көбүрөөк сарпташы мүмкүн.\n\nЭгер бул уруксат өчүрүлсө, колдонмодогу ойготкучтар жана графикке киргизилген башка аракеттер иштебейт."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, ойготкуч, эстеткич, саат"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Тынчымды алба"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Күйгүзүү"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Тынчымды алба\" режимин күйгүзүү"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Эч качан"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Узактыгы"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ар дайым суралсын"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Бул функция өчүрүлгөнгө чейин"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Аты жок)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Жаңы эле"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ушул телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ушул планшет"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index f6a2681..d99759b 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ອະນຸຍາດການໂຫລດຊັ້ນຂໍ້ມູນດີບັກ GPU ສຳລັບແອັບດີບັກ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ເປີດໃຊ້ການບັນທຶກຜູ້ຂາຍແບບລະອຽດ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ຮວມທັງການລາຍງານຂໍ້ຜິດພາດການເຂົ້າສູ່ລະບົບຂອງຜູ້ຂາຍສະເພາະອຸປະກອນເພີ່ມເຕີມ, ເຊິ່ງອາດມີຂໍ້ມູນສ່ວນຕົວ, ໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ ແລະ/ຫຼື ໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນເພີ່ມເຕີມ."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"ຂະໜາດໜ້າຈໍຂອງອະນິເມຊັນ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ຂະໜາດສະຫຼັບອະນິເມຊັນ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ໄລຍະເວລາອະນິເມຊັນ"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ໂມງປຸກ ແລະ ການແຈ້ງເຕືອນ"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ອະນຸຍາດໃຫ້ແອັບນີ້ຕັ້ງໂມງປຸກ ແລະ ກຳນົດເວລາຄຳສັ່ງທີ່ເນັ້ນເລື່ອງເວລາເປັນສຳຄັນໄດ້. ນີ້ຈະເຮັດໃຫ້ແອັບເຮັດວຽກໄດ້ໃນພື້ນຫຼັງ, ເຊິ່ງອາດໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ.\n\nຫາກປິດການອະນຸຍາດນີ້ໄວ້, ໂມງປຸກທີ່ມີຢູ່ກ່ອນແລ້ວ ແລະ ເຫດການທີ່ອ້າງອີງເວລາທີ່ກຳນົດໄວ້ໂດຍແອັບນີ້ຈະບໍ່ສາມາດເຮັດວຽກໄດ້."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ກຳນົດເວລາ, ໂມງປຸກ, ການແຈ້ງເຕືອນ, ໂມງ"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ຫ້າມລົບກວນ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ເປີດ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ເປີດໂໝດຫ້າມລົບກວນ"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ບໍ່ໃຊ້"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ໄລຍະເວລາ"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ຖາມທຸກເທື່ອ"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"ຈົນກວ່າທ່ານຈະປິດ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ບໍ່ມີຊື່)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ຕອນນີ້"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ໂທລະສັບນີ້"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ແທັບເລັດນີ້"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 4abde8f..204afc7 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Leisti įkelti graf. proc. der. sluoks. der. progr."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Įg. daugiaž. pasl. teik. reg."</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Į pranešimus apie riktą įtraukiami papildomi konkretaus įrenginio paslaugų teikėjo žurnalai, kuriuose gali būti privačios informacijos, kurie gali naudoti daugiau akumuliatoriaus energijos ir (arba) daugiau vietos saugykloje."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Lango animacijos mast."</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Animuoto perėjimo mast."</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator. trukmės skalė"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signalai ir priminimai"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Leiskite šiai programai nustatyti signalus ir suplanuoti veiksmus, kuriems svarbus laiko veiksnys. Dėl to programa gali veikti fone ir sunaudoti daugiau akumuliatoriaus energijos.\n\nJei šis leidimas išjungtas, šios programos suplanuoti esami signalai ir laiku pagrįsti įvykiai neveiks."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tvarkaraštis, signalas, priminimas, laikrodis"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Netrukdymo režimas"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Įjungti"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Netrukdymo režimo įjungimas"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Niekada"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trukmė"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Klausti kaskart"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Kol išjungsite"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nėra pavadinimo)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Ką tik"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Šis telefonas"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Šis planšetinis kompiuteris"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index a8c3f5a..71d11d5 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Atļaut GPU atkļūd. slāņu ielādi atkļūd. lietotnēm"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Iespējot izvērsto reģistrēšanu"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Iekļaut kļūdu pārskatos konkrētas ierīces papildu nodrošinātāju žurnālus (var iekļaut privātu informāciju, patērēt vairāk akumulatora enerģijas un/vai aizņemt vairāk vietas krātuvē)."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Loga animācijas mērogs"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Pārejas animācijas mērogs"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animācijas ilguma mērogs"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signāli un atgādinājumi"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Atļaujiet šai lietotnei iestatīt signālus un ieplānot darbības, kas jāveic konkrētā laikā. Tādējādi lietotne darbosies fonā un, iespējams, patērēs vairāk akumulatora enerģijas.\n\nJa šī atļauja nav piešķirta, esošie signāli un šīs lietotnes ieplānotie notikumi, kas jāizpilda konkrētā laikā, nedarbosies."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ieplānot, signāls, atgādinājums, pulkstenis"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Netraucēt"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ieslēgt"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Režīma “Netraucēt” ieslēgšana"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nekad"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Ilgums"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vaicāt katru reizi"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Līdz brīdim, kad izslēgsiet"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nav vārda)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Tikko"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Šis tālrunis"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Šis planšetdators"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index b2456d3..537f8b5 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дозволи вчитување GPU-слоеви за отстранув. грешки"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширна евиденција на продавачи"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Вклучува дополнителна евиденција на продавачи во извештаите за грешки за конкретен уред, којашто може да содржи приватни податоци, повеќе да ја користи батеријата и/или да користи повеќе капацитет."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Брзина на анимации за прозорци"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Брзина на преодни анимации"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Брзина на општи анимации"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и потсетници"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволете ѝ на апликацијава да поставува аларми и да закажува дејства со временски рокови. Ова овозможува апликацијата да работи во заднина и така може повеќе да ја троши батеријата.\n\nАко дозволава е исклучена, нема да функционираат постојните аларми и настаните според време закажани од апликацијава."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"закажување, аларм, потсетник, часовник"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не вознемирувај"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Вклучи"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Исклучување на „Не вознемирувај“"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никогаш"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Времетраење"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Прашувај секогаш"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Додека не го исклучите"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без име)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Пред малку"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Овој телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Овој таблет"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 9cf6268..c096260 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ഡീബഗ് ആപ്പുകൾക്കായി GPU ഡീബഗ് ലെയറുകൾ ലോഡ് ചെയ്യാൻ അനുവദിക്കുക"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"വെർബോസ് വെണ്ടർ ലോഗ് ചെയ്യൽ പ്രവർത്തനക്ഷമമാക്കൂ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ബഗ് റിപ്പോർട്ടുകളിൽ ഉപകരണ-നിർദ്ദിഷ്ട വെണ്ടർ അധിക ലോഗുകൾ ഉൾപ്പെടുത്തുക, അതിൽ സ്വകാര്യ വിവരങ്ങൾ അടങ്ങിയിരിക്കാം, കൂടുതൽ ബാറ്ററി ഉപയോഗിക്കാം കൂടാതെ/അല്ലെങ്കിൽ കൂടുതൽ സ്റ്റോറേജ് ഇടം ഉപയോഗിക്കാം."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"വിൻഡോ ആനിമേഷൻ സ്കെയിൽ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ട്രാൻസിഷൻ ആനിമേഷൻ സ്കെയിൽ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ആനിമേറ്റർ ദൈർഘ്യ സ്കെയിൽ"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"അലാറങ്ങളും റിമെെൻഡറുകളും"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"അലാറങ്ങൾ സജ്ജീകരിക്കാനും സമയപ്രാധാന്യമുള്ള പ്രവർത്തനങ്ങൾ ഷെഡ്യൂൾ ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കുക. പശ്ചാത്തലത്തിൽ റൺ ചെയ്യാൻ ഇത് ഈ ആപ്പിന് അനുവാദം നൽകുന്നു, ഇതിന് കൂടുതൽ ബാറ്ററി ഉപയോഗിച്ചേക്കാം.\n\nഈ അനുമതി ഓഫാണെങ്കിൽ, ഈ ആപ്പ് നിലവിൽ ഷെഡ്യൂൾ ചെയ്ത അലാറങ്ങളും സമയാധിഷ്ഠിത ഇവന്റുകളും പ്രവർത്തിക്കില്ല."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ഷെഡ്യൂൾ, അലാറം, റിമെെൻഡർ, ക്ലോക്ക്"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ശല്യപ്പെടുത്തരുത്"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ഓണാക്കുക"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കുക"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ഒരിക്കലും വേണ്ട"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ദൈർഘ്യം"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"എപ്പോഴും ചോദിക്കുക"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"നിങ്ങൾ ഓഫാക്കുന്നത് വരെ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(പേരില്ല)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ഇപ്പോൾ"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ഈ ഫോൺ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ഈ ടാബ്ലെറ്റ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 436326e..b3bca99 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дебаг хийх аппад GPU дебаг хийх давхарга ачаалахыг зөвшөөрөх"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Нийлүүлэгчийн дэлгэрэнгүй логийг идэвхжүүлэх"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Төхөөрөмжийн тодорхойлсон нийлүүлэгчийн нэвтрэх үеийн алдааны нэмэлт мэдээг оруулах бөгөөд энэ нь хувийн мэдээлэл агуулж, батарейг илүү ашиглах болон/эсвэл хадгалах сан илүү ашиглаж болзошгүй."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Цонхны анимацийн масштаб"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Шилжилтийн анимацийн масштаб"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимацийн хугацааны масштаб"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Сэрүүлэг, сануулагч"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Энэ аппад сэрүүлэг тавих болон хугацаанд мэдрэг үйлдлийн хуваарь гаргахыг зөвшөөрнө үү. Энэ нь аппад ард ажиллахыг зөвшөөрөх бөгөөд ингэснээр илүү их батарей ашиглаж магадгүй.\n\nХэрэв энэ зөвшөөрөл унтраалттай бол энэ аппын аль хэдийн тавьсан сэрүүлэг болон хуваарь гаргасан хугацаанд мэдрэг үйл явдал ажиллахгүй."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"хуваарь, сэрүүлэг, сануулагч, цаг"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Бүү саад бол"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Асаах"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Бүү саад бол горимыг асаах"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Хэзээ ч үгүй"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Хугацаа"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Тухай бүрд асуух"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Таныг унтраах хүртэл"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Нэр байхгүй)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Дөнгөж сая"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Энэ утас"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Энэ таблет"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index b68fc71..f6467fa 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डीबग अॅप्ससाठी GPU डीबग स्तर लोड करण्याची अनुमती द्या"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"व्हर्बोझ विक्रेता लॉगिंग सुरू करा"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"बग रिपोर्टमध्ये अतिरिक्त डिव्हाइस-विशिष्ट विक्रेता लॉगचा समावेश करा ज्यामध्ये खाजगी माहिती असू शकते, अधिक बॅटरी आणि/किंवा अधिक स्टोरेज वापरले जाईल."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"विंडो ॲनिमेशन स्केल"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांझिशन ॲनिमेशन स्केल"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ॲनिमेटर कालावधी स्केल"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म आणि रिमाइंडर"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"या ॲपला अलार्म सेट करण्याची किंवा वेळेनुसार संवेदनशील असलेल्या कृती शेड्युल करण्याची अनुमती द्या. हे ॲपला बॅकग्राउंडमध्ये रन होऊ देते, ज्यामुळे जास्त बॅटरी वापरली जाऊ शकते.\n\nही परवानगी बंद असल्यास, सध्याचे अलार्म आणि या ॲपद्वारे शेड्युल केलेले वेळेवर आधारित इव्हेंट काम करणार नाहीत."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्युल, अलार्म, रिमाइंडर, घड्याळ"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"व्यत्यय आणू नका"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सुरू करा"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका सुरू करा"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कधीही नाही"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"कालावधी"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"प्रत्येक वेळी विचारा"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"तुम्ही बंद करेपर्यंत"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(नाव नाही)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"आत्ताच"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"हा फोन"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"हा टॅबलेट"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 9da1d60..3301b54 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Benarkan pemuatan lapisan nyahpepijat GPU untuk apl penyahpepijatan"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Dayakan pengelogan vendor berjela"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sertakan log tambahan vendor khusus peranti dalam laporan pepijat, yang mungkin mengandungi maklumat peribadi, menggunakan lebih banyak kuasa bateri dan/atau menggunakan lebih banyak storan."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animasi tetingkap"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi peralihan"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala tempoh juruanimasi"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Penggera & peringatan"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Benarkan apl ini menetapkan penggera dan menjadualkan tindakan yang sensitif masa. Hal ini membolehkan apl berjalan di latar, yang mungkin menggunakan lebih banyak bateri.\n\nJika kebenaran ini dimatikan, penggera sedia ada dan acara berdasarkan masa yang dijadualkan oleh apl ini tidak akan berfungsi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadual, penggera, peringatan, jam"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Jangan Ganggu"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Hidupkan"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Hidupkan Jangan Ganggu"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jangan sekali-kali"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Tempoh"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Tanya setiap kali"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Sehingga anda matikan"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Tiada nama)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Sebentar tadi"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Telefon ini"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tablet ini"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index aa21f3c..79f1bc3 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"အမှားရှာအက်ပ်များအတွက် GPU အမှားရှာအလွှာများ ဖွင့်ခွင့်ပြုသည်"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"အကျယ်ရှင်းလင်းချက်ပံ့ပိုးသူ မှတ်တမ်းဖွင့်ရန်"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ချွတ်ယွင်းမှု အစီရင်ခံချက်တွင် စက်ပစ္စည်းအလိုက် ထုတ်လုပ်သူမှတ်တမ်းများကို ထည့်သွင်းခြင်းဖြင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များ ပါဝင်ခြင်း၊ ဘက်ထရီပိုသုံးခြင်း နှင့်/သို့မဟုတ် သိုလှောင်ခန်းပိုသုံးခြင်းတို့ ဖြစ်စေနိုင်သည်။"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"လှုပ်ရှားသက်ဝင်ပုံစကေး"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"သက်ဝင်အသွင်ပြောင်းခြင်း"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"လှုပ်ရှားမှုကြာချိန်စကေး"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"နှိုးစက်နှင့် သတိပေးချက်များ"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"နှိုးစက်သတ်မှတ်ရန်နှင့် အချိန်တိကျရန် လိုအပ်သည့် လုပ်ဆောင်ချက်များအတွက် အစီအစဉ်ဆွဲရန် ဤအက်ပ်ကို ခွင့်ပြုသည်။ ၎င်းက အက်ပ်ကို နောက်ခံတွင် လုပ်ဆောင်ခွင့်ပေးပြီး ဘက်ထရီပိုသုံးနိုင်သည်။\n\nဤခွင့်ပြုချက်ကို ပိတ်ထားပါက ဤအက်ပ်ဖြင့် အစီအစဉ်ဆွဲထားသော လက်ရှိနှိုးစက်နှင့် အချိန်သတ်မှတ်ထားသည့် အစီအစဉ်များ အလုပ်လုပ်တော့မည် မဟုတ်ပါ။"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"အချိန်ဇယား၊ နှိုးစက်၊ သတိပေးချက်၊ နာရီ"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"မနှောင့်ယှက်ရ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ဖွင့်ရန်"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'မနှောင့်ယှက်ရ\' ဖွင့်ခြင်း"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ဘယ်တော့မှ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ကြာချိန်"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"အမြဲမေးရန်"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"သင်ပိတ်လိုက်သည် အထိ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(အမည်မရှိ)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ယခုလေးတင်"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ဤဖုန်း"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ဤတက်ဘလက်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 1a672c39..23031c3 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillat GPU-feilsøkingslag for feilsøkingsapper"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Detaljert leverandørlogging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inkluder flere enhetsspesifikke leverandørlogger i feilrapporter, som kan inneholde privat informasjon, bruke mer batteri og/eller bruke mer lagringsplass."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Animasjonsskala for vindu"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Animasjonsskala for overgang"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Varighetsskala for animasjoner"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmer og påminnelser"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Gi denne appen tillatelse til å angi alarmer og planlegge tidssensitive handlinger. Dette gir appen tillatelse til å kjøre i bakgrunnen, noe som kan bruke mer batteri.\n\nHvis denne tillatelsen er av, fungerer ikke eksisterende alarmer og tidsbaserte hendelser som er planlagt av denne appen."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tidsplan, alarm, påminnelse, klokke"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ikke forstyrr"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Slå på"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Slå på Ikke forstyrr"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldri"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Varighet"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Spør hver gang"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Til du slår av"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Uten navn)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Nå nettopp"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Denne telefonen"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Dette nettbrettet"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 1e33f88..38e137d 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -136,7 +136,7 @@
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD अडियो"</string>
<string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"हियरिङ डिभाइसहरू"</string>
<string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE अडियो"</string>
- <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="5757754050938807276">"श्रवण यन्त्रहरूमा जडान गरियो"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="5757754050938807276">"हियरिङ डिभाइसमा कनेक्ट गरियो"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE अडियोमा कनेक्ट गरिएको छ"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"मिडिया अडियोसँग जडित"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"फोन अडियोमा जडान गरियो"</string>
@@ -154,7 +154,7 @@
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"फोन अडियोको लागि प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"फाइल ट्रान्सफरका लागि प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"इनपुटको लागि प्रयोग गर्नुहोस्"</string>
- <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="3374057355721486932">"श्रवण यन्त्रहरूका लागि प्रयोग गर्नुहोस्"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="3374057355721486932">"हियरिङ डिभाइसका लागि प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIO मा प्रयोग गर्नुहोस्"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"कनेक्ट गर्नुहोस्"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"जोडी"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डिबग एपका लागि GPU का डिबग लेयर लोड गर्नुहोस्"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"भर्बोज भेन्डर लगिङ अन गर्नुहोस्"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"बग रिपोर्टहरूमा डिभाइस विशेषका विक्रेताका अतिरिक्त लगहरू समावेश गर्नुहोस्। यी लगमा निजी जानकारी समावेश हुन सक्छन्, यिनले ब्याट्रीको खपत बढाउन र/वा थप भण्डारण प्रयोग गर्न सक्छन्।"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"विन्डो एनिमेसन स्केल"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"संक्रमण एनिमेसन स्केल"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"एनिमेसनको अवधि मापन"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म तथा रिमाइन्डर"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"यो एपलाई अलार्म सेट गर्ने र समयमै पूरा गर्नु पर्ने कारबाहीहरूको रुटिन बनाउने अनुमति दिनुहोस्। यो अनुमति दिइएको छ भने यो एप ब्याकग्राउन्डमा चल्छ र धेरै ब्याट्री खपत हुन्छ।\n\nयो अनुमति दिइएको छैन भने सेट गरिएका अलार्म बज्दैनन् र यो एपले तय गरेका गतिविधि चल्दैनन्।"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"समयतालिका, अलार्म, रिमाइन्डर, घडी"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"बाधा नपुऱ्याउनुहोस्"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"अन गर्नुहोस्"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"बाधा नपुऱ्याउनुहोस् नामक मोडलाई अन गर्नुहोस्"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कहिल्यै होइन"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"अवधि"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"प्रत्येक पटक सोध्नुहोस्"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"तपाईंले अफ नगरेसम्म"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(कुनै नाम छैन)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"अहिले भर्खरै"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"यो फोन"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यो ट्याब्लेट"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 226f592..9e0088f 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Sta laden van GPU-foutopsporingslagen toe voor foutopsporingsapps"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Uitgebreide leverancierslogboeken aanzetten"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Neem aanvullende apparaatspecifieke leverancierslogboeken op in bugrapporten. Deze kunnen privégegevens bevatten, meer batterijlading gebruiken en/of meer opslagruimte gebruiken"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Vensteranimatieschaal"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangsanimatieschaal"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Duur van animatieschaal"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wekkers en herinneringen"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Sta toe dat deze app wekkers zet en tijdgevoelige acties plant. De app kan hierdoor op de achtergrond worden uitgevoerd, waardoor je misschien meer batterijlading verbruikt.\n\nAls dit recht uitstaat, werken door deze app geplande bestaande wekkers en tijdgebaseerde afspraken niet."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plannen, schema, wekker, alarm, herinnering, klok"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Niet storen"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aanzetten"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zet Niet storen aan."</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nooit"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duur"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Altijd vragen"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Totdat je uitzet"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Geen naam)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Zojuist"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Deze telefoon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Deze tablet"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 562a558..8d4e5cc 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -125,7 +125,7 @@
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"ମିଡିଆ ଅଡିଓ"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"ଫୋନ କଲ"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ଫାଇଲ୍ ଟ୍ରାନ୍ସଫର୍"</string>
- <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ଇନ୍ପୁଟ୍ ଡିଭାଇସ୍"</string>
+ <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ଇନପୁଟ ଡିଭାଇସ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ଇଣ୍ଟରନେଟ ଆକ୍ସେସ"</string>
<string name="bluetooth_profile_pbap" msgid="2103406516858653017">"କଣ୍ଟାକ୍ଟ ଓ କଲ ଇତିହାସକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"ସୂଚନାକୁ କଲ ଘୋଷଣା ଏବଂ ଆହୁରି ଅଧିକ ପାଇଁ ବ୍ୟବହାର କରାଯିବ"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ଡିବଗ୍ ଆପ୍ଗୁଡ଼ିକ ପାଇଁ GPU ଡିବଗ୍ ଲେୟର୍ ଲୋଡ୍ କରିବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ଭର୍ବୋସ ଭେଣ୍ଡର୍ ଲଗିଂ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ବଗ୍ ରିପୋର୍ଟଗୁଡ଼ିକରେ ଅତିରିକ୍ତ ଡିଭାଇସ୍-ନିର୍ଦ୍ଦିଷ୍ଟ ଲଗଗୁଡ଼ିକ ସାମିଲ କରନ୍ତୁ, ଯେଉଁଥିରେ ବ୍ୟକ୍ତିଗତ ସୂଚନା ଥାଇପାରେ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ଏବଂ/କିମ୍ବା ଅଧିକ ଷ୍ଟୋରେଜ୍ ବ୍ୟବହାର କରିପାରେ।"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"ୱିଣ୍ଡୋ ଆନିମେସନ୍ ସ୍କେଲ୍"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ଟ୍ରାଞ୍ଜିସନ୍ ଆନିମେସନ୍ ସ୍କେଲ୍"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ଆନିମେଟର୍ ଅବଧି ସ୍କେଲ୍"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ଏହି ଆପକୁ ଆଲାରାମ୍ ସେଟ୍ କରିବାକୁ ଏବଂ ସମୟ-ସମ୍ବେଦନଶୀଳ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ସିଡୁଲ୍ କରିବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଏହା ଆପକୁ ପୃଷ୍ଠପଟରେ ଚାଲିବାକୁ ଦେଇଥାଏ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରିପାରେ।\n\nଯଦି ଏହି ଅନୁମତି ବନ୍ଦ ଅଛି, ତେବେ ଏହି ଆପ୍ ଦ୍ୱାରା ସିଡୁଲ୍ କରାଯାଇଥିବା ପୂର୍ବରୁ ଥିବା ଆଲାରାମ୍ ଏବଂ ସମୟ-ଆଧାରିତ ଇଭେଣ୍ଟଗୁଡ଼ିକ କାମ କରିବ ନାହିଁ।"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ସିଡୁଲ୍, ଆଲାରାମ୍, ରିମାଇଣ୍ଡର୍, ଘଣ୍ଟା"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ଚାଲୁ କରନ୍ତୁ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ କରନ୍ତୁ"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"କଦାପି ନୁହେଁ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ଅବଧି"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ପ୍ରତ୍ୟେକ ଥର ପଚାରନ୍ତୁ"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"ଆପଣ ବନ୍ଦ ନକରିବା ପର୍ଯ୍ୟନ୍ତ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(କୌଣସି ନାମ ନାହିଁ)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ଏହିକ୍ଷଣି"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ଏହି ଫୋନ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ଏହି ଟାବଲେଟ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index f80ec8d..54c9b54 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -316,7 +316,7 @@
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ਬਲੂਟੁੱਥ ਆਡੀਓ LDAC ਕੋਡੇਕ: ਪਲੇਬੈਕ ਕੁਆਲਿਟੀ"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ਬਲੂਟੁੱਥ ਆਡੀਓ LDAC\nਕੋਡੇਕ ਚੋਣ ਨੂੰ ਟ੍ਰਿਗਰ ਕਰੋ: ਪਲੇਬੈਕ ਕੁਆਲਿਟੀ"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"ਸਟ੍ਰੀਮਿੰਗ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
- <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ਨਿੱਜੀ DNS"</string>
+ <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ਪ੍ਰਾਈਵੇਟ DNS"</string>
<string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"ਨਿੱਜੀ DNS ਮੋਡ ਚੁਣੋ"</string>
<string name="private_dns_mode_off" msgid="7065962499349997041">"ਬੰਦ"</string>
<string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ਸਵੈਚਲਿਤ"</string>
@@ -407,7 +407,19 @@
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"GPU ਡੀਬੱਗ ਤਹਿਆਂ ਚਾਲੂ ਕਰੋ"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ਡੀਬੱਗ ਐਪਾਂ ਲਈ GPU ਡੀਬੱਗ ਤਹਿਆਂ ਨੂੰ ਲੋਡ ਹੋਣ ਦਿਓ"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ਵਰਬੋਸ ਵਿਕਰੇਤਾ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਵਧੀਕ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਵਿਕਰੇਤਾ ਲੌਗ ਸ਼ਾਮਲ ਕਰੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਨਿੱਜੀ ਜਾਣਕਾਰੀ, ਬੈਟਰੀ ਦੀ ਵਧੇਰੇ ਵਰਤੋਂ, ਅਤੇ/ਜਾਂ ਵਧੇਰੀ ਸਟੋਰੇਜ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਵਧੀਕ ਡੀਵਾਈਸ ਮੁਤਾਬਕ ਵਿਕਰੇਤਾ ਲੌਗ ਸ਼ਾਮਲ ਕਰੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਪ੍ਰਾਈਵੇਟ ਜਾਣਕਾਰੀ, ਬੈਟਰੀ ਦੀ ਵਧੇਰੇ ਵਰਤੋਂ ਅਤੇ/ਜਾਂ ਜ਼ਿਆਦਾ ਸਟੋਰੇਜ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"ਵਿੰਡੋ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ਟ੍ਰਾਂਜ਼ਿਸ਼ਨ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ਐਨੀਮੇਟਰ ਮਿਆਦ ਸਕੇਲ"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਜਾਂ ਹੋਰ ਸਮਾਂ-ਸੰਵੇਦਨਸ਼ੀਲ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦਿਓ। ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵੱਧ ਸਕਦੀ ਹੈ।\n\nਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੈ, ਤਾਂ ਇਸ ਐਪ ਰਾਹੀਂ ਨਿਯਤ ਕੀਤੇ ਮੌਜੂਦਾ ਅਲਾਰਮ ਅਤੇ ਸਮਾਂ-ਆਧਾਰਿਤ ਇਵੈਂਟ ਕੰਮ ਨਹੀਂ ਕਰਨਗੇ।"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ਸਮਾਂ-ਸੂਚੀ, ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਘੜੀ"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ਚਾਲੂ ਕਰੋ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ਕਦੇ ਵੀ ਨਹੀਂ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ਮਿਆਦ"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ਹਰ ਵਾਰ ਪੁੱਛੋ"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਬੰਦ ਨਹੀਂ ਕਰਦੇ"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ਕੋਈ ਨਾਮ ਨਹੀਂ)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ਹੁਣੇ ਹੀ"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ਇਹ ਫ਼ੋਨ"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ਇਹ ਟੈਬਲੈੱਟ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 8babb8b..ef09687 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Zezwalaj na ładowanie warstw debugowania GPU"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Włącz szczegółowe rejestrowanie dostawcy"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Dołączaj do raportów o błędach dodatkowe dane dostawcy dotyczące konkretnego urządzenia, które mogą zawierać dane prywatne oraz wykorzystywać więcej baterii lub pamięci"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacji okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacji przejścia"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala długości animacji"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmy i przypomnienia"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Zezwalaj tej aplikacji na ustawianie alarmów i planowanie działań, w przypadku których czas jest istotny. Aplikacja będzie mogła działać w tle, co może zwiększyć wykorzystanie baterii.\n\nJeśli nie włączysz tego uprawnienia, istniejące alarmy i zaplanowane wydarzenia z tej aplikacji nie będą działać."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"harmonogram, alarm, przypomnienie, zegar"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Nie przeszkadzać"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Włącz"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Włącz tryb Nie przeszkadzać"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nigdy"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Czas"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Zawsze pytaj"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Dopóki nie wyłączysz"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez nazwy)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Przed chwilą"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ten telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ten tablet"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 337b011..e441f05 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permitir carregamento de camadas de depuração de GPU p/ apps de depuração"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativar registro detalhado de fornecedor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluir mais registros de fornecedores específicos do dispositivo em relatórios de bugs. Isso pode aumentar o uso da bateria e/ou do armazenamento, e os relatórios podem conter informações particulares."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação da janela"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração do Animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações com hora marcada. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Não perturbe"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Até você desativar"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sem nome)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telefone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index a40b95f..7aed3f4 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite carregamento de camadas de depuração de GPU para apps de depuração"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativ. registo do fornecedor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclua registos adicionais de fornecedores específicos de dispositivos em relatórios de erros, que podem conter informações privadas, utilizar mais bateria e/ou utilizar mais armazenamento."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação de transição"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração de animação"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permita que a app defina alarmes e agende ações com um horário específico. Esta ação permite que a app seja executada em segundo plano, o que pode usar mais bateria.\n\nSe esta autorização estiver desativada, os alarmes existentes e os eventos com base no tempo agendados por esta app não funcionam."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"agendar, alarme, lembrete, relógio"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Não incomodar"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o modo Não incomodar"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Até desativar"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sem nome)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telemóvel"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 337b011..e441f05 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permitir carregamento de camadas de depuração de GPU p/ apps de depuração"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativar registro detalhado de fornecedor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluir mais registros de fornecedores específicos do dispositivo em relatórios de bugs. Isso pode aumentar o uso da bateria e/ou do armazenamento, e os relatórios podem conter informações particulares."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação da janela"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração do Animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações com hora marcada. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Não perturbe"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Até você desativar"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sem nome)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telefone"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4bddeb9a..9a79bdf 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite încărcarea nivelurilor de depanare GPU pentru aplicațiile de depanare"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activează înregistrarea detaliată a furnizorilor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include alte jurnale ale furnizorilor de dispozitive în rapoartele de eroare, care pot conține informații private, folosește mai multă baterie și/sau mai mult spațiu de stocare."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Scară animație fereastră"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Scară tranziție animații"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Scară durată Animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarme și mementouri"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite acestei aplicații să seteze alarme și să planifice acțiuni care trebuie realizate în timp scurt. Astfel, aplicația poate să ruleze în fundal, ceea ce ar putea crește consumul de baterie.\n\nDacă permisiunea este dezactivată, alarmele și evenimentele dependente de timp planificate de aplicație nu vor funcționa."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programare, alarmă, memento, ceas"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Nu deranja"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activează"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activează Nu deranja"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Niciodată"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durată"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Întreabă de fiecare dată"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Până când dezactivezi"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Fără nume)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Chiar acum"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Acest telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Această tabletă"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index f30a125..b768cd9 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Включить загрузку слоев отладки графического процессора"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Подробный журнал поставщика"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включать в информацию об ошибках дополнительные записи поставщика об устройстве, которые могут содержать личные данные и занимать больше места. Также это может увеличить расход заряда батареи."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Анимация окон"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Анимация переходов"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Длительность анимации"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будильники и напоминания"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Вы можете разрешить этому приложению устанавливать будильники и планировать запуск действий в определенное время. В этом случае оно будет работать в фоновом режиме и быстрее расходовать заряд батареи.\n\nЕсли отключить это разрешение, текущие будильники и созданные приложением события перестанут запускаться."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"установить, будильник, напоминание, часы"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не беспокоить"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включить"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включите режим \"Не беспокоить\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никогда"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Длительность"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Всегда спрашивать"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Пока вы не отключите"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"Имя не указано"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Только что"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Этот смартфон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Этот планшет"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 9f1aca6..e6095e8 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"නිදොසීමේ යෙදුම්වලට GPU නිදොසීමේ ස්තර පූරණයට ඉඩ දෙ."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"verbose vendor පිරීම සබල කරන්න"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"පුද්ගලික තොරතුරු අන්තර්ගත විය හැකි, වැඩි බැටරි බලයක් භාවිත කිරීමට සහ/හෝ වැඩි ගබඩා ඉඩක් භාවිත කිරීමට හැකි අමතර උපාංග නිශ්චිත විකුණුම්කරු ලොග, දෝෂ වාර්තාවල අඩංගු වේ."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"කවුළු සජීවිකරණ පරිමාණය"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"සංක්රමණ සජීවන පරිමාණය"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"සජීවක කාල පරාස පරිමාණය"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"එලාම සහ සිහිකැඳවීම්"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"එලාම සැකසීමට සහ කාල සංවේදී ක්රියා කාලසටහන්ගත කිරීමට මෙම යෙදුමට ඉඩ දෙන්න. මෙය පසුබිමේ ධාවනය වීමට යෙදුමට ඉඩ දෙයි, එය වැඩි බැටරිය වැඩියෙන් භාවිත කළ හැකිය.\n\nමෙම අවසරය ක්රියාවිරහිත නම්, මෙම යෙදුම මඟින් සැලසුම් කර ඇති තිබෙන එලාම සහ වේලාව පදනම් කර ගත් සිදුවීම් ක්රියා නොකරනු ඇත."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"කාල සටහන, එලාමය, සිහිකැඳවීම, ඔරලෝසුව"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"බාධා නොකරන්න"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ක්රියාත්මක කරන්න"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"බාධා නොකරන්න ක්රියාත්මක කරන්න"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"කිසි විටක නැත"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"කාල සීමාව"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"සෑම විටම ඉල්ලන්න"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"ඔබ ක්රියාවිරහිත කරන තුරු"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(නමක් නොමැත)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"මේ දැන්"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"මෙම දුරකථනය"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"මෙම ටැබ්ලටය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index db8301a..3173362 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -261,7 +261,7 @@
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Spárované zariadenia"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Aktuálne pripojené"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Podrobnosti o zariadení"</string>
- <string name="adb_device_forget" msgid="193072400783068417">"Odstrániť"</string>
+ <string name="adb_device_forget" msgid="193072400783068417">"Zabudnúť"</string>
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Digitálny odtlačok zariadenia: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Pripojenie zlyhalo"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Skontrolujte, či je zariadenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g> pripojené k správnej sieti"</string>
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Povoliť načítanie vrstiev ladenia grafického procesora na ladenie aplikácií"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivovať podrobný zápis dodávateľov do denníka"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Zahŕňať do hlásení chýb ďalšie denníky dodávateľa pre konkrétne zariadenie, ktoré môžu obsahovať osobné údaje, zvýšiť spotrebu batérie alebo zabrať viac ukladacieho priestoru"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Mierka animácie okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Mierka animácie premeny"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Mierka dĺžky animácie"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Budíky a pripomenutia"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Povoľte tejto aplikácii nastavovať budíky a plánovať akcie s časovým obmedzením. Aplikácii to umožní pracovať na pozadí, čo môže zvýšiť spotrebu batérie.\n\nAk je toto povolenie vypnuté, existujúce budíky a udalosti s časovým obmedzením naplánované touto aplikáciou nebudú fungovať."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, pripomenutie, hodiny"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Režim bez vyrušení"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnúť"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapnite režim bez vyrušení"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikdy"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trvanie"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vždy sa opýtať"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Dokým funkciu nevypnete"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez mena)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Teraz"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tento telefón"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tento tablet"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 5460c3b..7ce5d46 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Aplikacijam za odpravljanje napak dovoli nalaganje slojev za odpravljanje napak GPE."</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogoči podrobno beleženje za ponudnika"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Vključi dodatne dnevnike ponudnika, odvisne od posamezne naprave, v poročila o napakah. Takšno poročilo lahko vsebuje zasebne podatke, porabi več energije baterije in/ali več shrambe."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Merilo animacije okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Merilo animacije prehoda"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Merilo trajanja animacije"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi in opomniki"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tej aplikaciji dovolite nastavljanje alarmov in načrtovanje časovno občutljivih dejanj. S tem aplikaciji omogočite izvajanje v ozadju, kar bo morda povečalo porabo energije baterije.\n\nČe je to dovoljenje izklopljeno, obstoječi alarmi in časovno občutljivi dogodki, ki jih nastavi ta aplikacija, ne bodo delovali."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"načrtovanje, urnik, alarm, opomnik, ura"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne moti"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vklopi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vklop načina »Ne moti«"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikoli"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vedno vprašaj"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Dokler ne izklopite"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ni imena)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Pravkar"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ta telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ta tablični računalnik"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 3db7146..313fbc2 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Lejo ngarkimin e shtresave të korrigjimit të GPU-së për aplikacionet e korrigjimit"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivizo evidencat e tregtuesit me shumë fjalë"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Përfshi evidenca shtesë të treguesve specifike për pajisjen në raportet e defekteve, që mund të përfshijnë informacion privat, mund të përdorin më shumë bateri dhe/ose të përdorin më shumë hapësirë ruajtëse."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Animacioni i dritares"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Animacioni kalimtar"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Kohëzgjatja e animatorit"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmet dhe alarmet rikujtuese"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lejo që ky aplikacion të caktojë alarmet dhe të planifikojë veprime që kanë një afat të caktuar. Kjo mundëson që aplikacioni të ekzekutohet në sfond, gjë që mund të përdorë më shumë bateri.\n\nNëse kjo leje është caktuar si joaktive, alarmet ekzistuese dhe ngjarjet në bazë kohore të planifikuara nga ky aplikacion nuk do të funksionojnë."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planifiko, alarm, alarm rikujtues, ora"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Mos shqetëso"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivizo"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivizo \"Mos shqetëso\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Asnjëherë"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Kohëzgjatja"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pyet çdo herë"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Derisa ta çaktivizosh"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Pa emër)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Pikërisht tani"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ky telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ky tablet"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index fa94c2e..217da2c 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Учитава отклањање грешака GPU-a у апл. за отклањање грешака"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширне евиденције продавца"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Уврштава у извештаје о грешкама додатне посебне евиденције продавца за уређаје, које могу да садрже приватне податке, да троше више батерије и/или да користе више меморије."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Размера анимације прозора"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Размера анимације прелаза"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматорова размера трајања"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и подсетници"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Омогућите овој апликацији да подешава аларме и заказује временски осетљиве радње. То омогућава да апликација буде покренута у позадини, што може да троши више батерије.\n\nАко је ова дозвола искључена, постојећи аларми и догађаји засновани на времену заказани помоћу ове апликације неће радити."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"заказати, аларм, подсетник, сат"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не узнемиравај"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Укључи"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Укључите режим Не узнемиравај"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никад"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Трајање"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Питај сваки пут"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Док не искључите"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без имена)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Управо"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Овај телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Овај таблет"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 636d969..38faa8c 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillåt att felsökningsappar läser in GPU-felsökningslager"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivera utförlig loggning för leverantörer"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Ta med ytterligare enhetsspecifika leverantörsloggar i felrapporter. Dessa kan innehålla privata uppgifter samt använda mer batteri och/eller mer lagringsutrymme."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala – fönsteranimering"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala – övergångsanimering"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Längdskala för Animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarm och påminnelser"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillåt att den här appen ställer in alarm och schemalägger tidskänsliga åtgärder. Om du tillåter detta kan appen köras i bakgrunden, vilket kan dra mer batteri.\n\nOm behörigheten är inaktiverad fungerar inte befintliga alarm och tidsbaserade händelser som schemalagts av den här appen."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schema, alarm, påminnelse, klocka"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Stör ej"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivera"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivera Stör ej."</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrig"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Varaktighet"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Fråga varje gång"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Tills du inaktiverar funktionen"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Inget namn)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Nyss"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Den här telefonen"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Den här surfplattan"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 01b786d..744a79e 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Ruhusu upakiaji wa safu za utatuzi wa GPU za programu za utatuzi"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Washa uwekaji kumbukumbu za muuzaji kwa kutumia sauti"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Jumuisha kumbukumbu zaidi za muuzaji ambazo ni mahususi kwa kifaa kwenye ripoti za hitilafu, ambazo huenda zikawa na maelezo ya faragha, zikatumia chaji nyingi ya betri na/au zikatumia nafasi kubwa ya hifadhi."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Uhuishaji kwenye dirisha"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Mageuzi ya kipimo cha uhuishaji"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Mizani ya muda wa uhuishaji"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Kengele na vikumbusho"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Ruhusu programu hii iweke kengele na ratiba za vitendo vingine vinavyotegemea wakati. Hatua hii inairuhusu programu itumike chinichini, hali inayoweza kutumia chaji nyingi ya betri.\n\nIkiwa ruhusa hii itazimwa, kengele zilizopo na ratiba za vitendo vinavyotegemea wakati zilizowekwa na programu hii hazitafanya kazi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ratiba, kengele, kikumbusho, saa"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Usinisumbue"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Washa"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Washa kipengele cha Usinisumbue"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Kamwe usiwashe"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Muda"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Uliza kila wakati"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Hadi utakapoizima"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Hakuna jina)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Sasa hivi"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Simu hii"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Kishikwambi hiki"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 8aaeb5d..113a139 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"பிழைத்திருத்த ஆப்ஸிற்கு, GPU பிழைத்திருத்த லேயர்களை ஏற்றுவதற்கு அனுமதி"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"வெர்போஸ் வெண்டார் பதிவை இயக்கு"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"பிழை அறிக்கைகளில் சாதனம் சார்ந்த கூடுதல் வெண்டார் பதிவுகளைச் சேர்க்கவும். அவற்றில் தனிப்பட்ட தகவல்கள், அதிக பேட்டரி உபயோகம் மற்றும்/அல்லது அதிக சேமிப்பிட உபயோகம் குறித்த தகவல்கள் இருக்கக்கூடும்."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"சாளர அனிமேஷன் வேகம்"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"அனிமேஷன் மாற்றத்தின் வேகம்"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"அனிமேட்டர் கால அளவு"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"அலாரங்கள் & நினைவூட்டல்கள்"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"அலாரங்களை அமைக்கவும் குறிப்பிட்ட கால இடைவெளியில் செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். இது ஆப்ஸ் பின்னணியில் இயங்குவதை அனுமதிக்கும், இதற்காக அதிக பேட்டரியைப் பயன்படுத்தக்கூடும்.\n\nஇந்த அனுமதி முடக்கப்பட்டிருந்தால் இந்த ஆப்ஸ் மூலம் திட்டமிடப்பட்ட ஏற்கெனவே அமைத்த அலாரங்களும் நேர அடிப்படையிலான நிகழ்வுகளும் வேலை செய்யாது."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"திட்டமிடல், அலாரம், நினைவூட்டல், கடிகாரம்"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"தொந்தரவு செய்யாதே"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ஆன் செய்"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"தொந்தரவு செய்ய வேண்டாம் என்பதை ஆன் செய்யும்"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ஒருபோதும் வேண்டாம்"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"கால அளவு"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ஒவ்வொரு முறையும் கேள்"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"ஆஃப் செய்யும் வரை"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(பெயர் இல்லை)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"சற்றுமுன்"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"இந்த மொபைல்"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"இந்த டேப்லெட்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 16d40c2..83f2faa 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"డీబగ్ యాప్ల కోసం GPU డీబగ్ లేయర్లను లోడ్ చేయడాన్ని అనుమతించండి"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"వివరణాత్మక వెండార్ లాగింగ్ను ఎనేబుల్ చేయండి"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"బగ్ రిపోర్ట్లలో అదనపు పరికర-నిర్దిష్ట వెండార్ లాగ్లను చేర్చండి, అవి ప్రైవేట్ సమాచారాన్ని కలిగి ఉండవచ్చు, మరింత బ్యాటరీని, మరియు/లేదా మరింత స్టోరేజ్ను ఉపయోగించవచ్చు."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"విండో యానిమేషన్ స్కేల్"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ట్రాన్సిషన్ యానిమేషన్ స్కేల్"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"యానిమేటర్ వ్యవధి స్కేల్"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"అలారాలు & రిమైండర్లు"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"అలారాలను సెట్ చేయడానికి, టైమ్-సెన్సిటివ్ చర్యలను షెడ్యూల్ చేయడానికి ఈ యాప్ను అనుమతించండి. ఇది యాప్ను బ్యాక్గ్రౌండ్లో రన్ అవడానికి అనుమతిస్తుంది, ఇది ఎక్కువ బ్యాటరీని ఉపయోగించవచ్చు.\n\nఈ అనుమతిని ఆఫ్ చేస్తే, ఈ యాప్ ద్వారా షెడ్యూల్ చేసినటువంటి ఇప్పటికే ఉన్న అలారాలు, టైమ్-ఆధారిత ఈవెంట్లు పనిచేయవు."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"షెడ్యూల్, అలారం, రిమైండర్, గడియారం"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"అంతరాయం కలిగించవద్దు"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ఆన్ చేయండి"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"అంతరాయం కలిగించవద్దును ఆన్ చేయండి"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ఎప్పటికీ వద్దు"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"వ్యవధి"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ప్రతిసారి అడగాలి"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"మీరు ఆఫ్ చేసే వరకు"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(పేరు లేదు)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ఇప్పుడే"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"ఈ ఫోన్"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ఈ టాబ్లెట్"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 014ba26..ef31592 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"อนุญาตให้โหลดเลเยอร์การแก้ไขข้อบกพร่อง GPU สำหรับแอปแก้ไขข้อบกพร่อง"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"เปิดการบันทึกเวนเดอร์แบบละเอียด"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"รวมบันทึกเวนเดอร์เพิ่มเติมเฉพาะอุปกรณ์ไว้ในรายงานข้อบกพร่อง ซึ่งอาจมีข้อมูลส่วนตัว ใช้แบตเตอรี่มากขึ้น และ/หรือใช้พื้นที่เก็บข้อมูลมากขึ้น"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"อัตราการเคลื่อนไหวของหน้าต่าง"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"อัตราการเคลื่อนไหวของการเปลี่ยนภาพ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"อัตราความเร็วตามตัวสร้างภาพเคลื่อนไหว"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"การปลุกและการช่วยเตือน"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"อนุญาตให้แอปนี้ตั้งปลุกและกำหนดเวลาการดำเนินการที่ต้องคำนึงถึงเวลาเป็นสำคัญ สิทธิ์นี้ช่วยให้แอปทำงานในเบื้องหลังได้ จึงอาจทำให้ใช้แบตเตอรี่มากขึ้น\n\nหากปิดใช้สิทธิ์นี้ การปลุกที่มีอยู่และกิจกรรมที่ต้องคำนึงถึงเวลาเป็นสำคัญซึ่งแอปนี้กำหนดเวลาไว้จะไม่ทำงาน"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"กำหนดเวลา การปลุก การช่วยเตือน นาฬิกา"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ห้ามรบกวน"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"เปิด"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"เปิด \"ห้ามรบกวน\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ไม่เลย"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ระยะเวลา"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ถามทุกครั้ง"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"จนกว่าคุณจะปิด"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ไม่มีชื่อ)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"เมื่อสักครู่"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"โทรศัพท์เครื่องนี้"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"แท็บเล็ตเครื่องนี้"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 936f521..90acd6fa 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Payagang i-load ang GPU debug layer sa debug app"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"I-enable ang verbose vendor logging"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Magsama sa mga ulat ng bug ng mga karagdagang log ng vendor na partikular sa device, na posibleng may pribadong impormasyon, gumamit ng mas maraming baterya, at/o gumamit ng mas malaking storage."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Scale ng window animation"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Scale ng transition animation"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Scale ng tagal ng animator"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Mga alarm at paalala"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Payagan ang app na ito na magtakda ng mga alarm at mag-iskedyul ng mga pagkilos na may limitadong oras. Papayagan nitong tumakbo ang app sa background, na posibleng gumamit ng mas maraming baterya.\n\nKung naka-off ang pahintulot na ito, hindi gagana ang mga kasalukuyang alarm at event na nakabatay sa oras na naiskedyul ng app na ito."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"iskedyul, alarm, paalala, orasan"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Huwag Istorbohin"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"I-on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"I-on ang Huwag Istorbohin"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hindi kailanman"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Tagal"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Magtanong palagi"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Hanggang sa i-off mo"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Walang pangalan)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Ngayon lang"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ang teleponong ito"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ang tablet na ito"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index e8bac31..a30c3ee 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Hata ayıklama uygulamaları için GPU hata ayıklama katmanlarının yüklenmesine izin ver"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ayrıntılı satıcı günlüğünü etkinleştir"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Hata raporlarına cihaza özgü ek satıcı günlükleri ekle. Bu günlükler gizli bilgiler içerebilir, daha fazla pil ve/veya daha fazla depolama alanı kullanabilir."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Pencere animasyonu ölçeği"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Geçiş animasyonu ölçeği"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatör süre ölçeği"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmlar ve hatırlatıcılar"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu uygulamanın alarm kurmasına ve zamana bağlı işlemler programlamasına izin verin. Bu izin, uygulamanın arka planda çalışmasına olanak sağlayarak daha fazla pil harcanmasına neden olabilir.\n\nBu izin verilmezse bu uygulama tarafından programlanmış mevcut alarmlar ve zamana bağlı etkinlikler çalışmaz."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"program, alarm, hatırlatıcı, saat"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Rahatsız Etmeyin"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aç"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Rahatsız Etmeyin\'i açın"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hiçbir zaman"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Süre"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Her zaman sor"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Siz kapatana kadar"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Adsız)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Az önce"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Bu telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Bu tablet"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index deb0a40..c94e745 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дозволити завантажувати шари налагодження ГП для додатків налагодження"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Увімкнути докладний журнал постачальника"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включати у звіти про помилки додаткові записи постачальника про пристрій, які можуть містити особисті дані, призводити до надмірного споживання заряду акумулятора та/або використовувати більший обсяг пам\'яті."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Анімація вікон"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Анімація переходів"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Тривалість анімації"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будильники й нагадування"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволити цьому додатку налаштовувати будильники й створювати розклад дій. Додаток зможе працювати у фоновому режимі й використовувати більше заряду акумулятора.\n\nЯкщо вимкнути такий дозвіл, наявні будильники й дії, створені цим додатком, не працюватимуть."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"запланувати, будильник, нагадування, годинник"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не турбувати"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Увімкнути"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Увімкнути режим \"Не турбувати\""</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ніколи"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Тривалість"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Запитувати щоразу"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Доки не вимкнути"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без імені)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Щойно"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Цей телефон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Цей планшет"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 3ac4d95..3d2c89c 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ڈیبگ ایپس کیلئے GPU ڈیبگ پرتوں کو لوڈ کرنے دیں"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"وربوس وینڈر لاگنگ فعال کریں"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"اضافی آلہ کے مخصوص وینڈر لاگز کو بگ رپورٹس میں شامل کریں، جن میں نجی معلومات، بیٹری کا زیادہ استعمال اور/یا اسٹوریج کا زیادہ استعمال شامل ہوسکتے ہیں۔"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"ونڈو اینیمیشن اسکیل"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ٹرانزیشن اینیمیشن اسکیل"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"اینیمیٹر دورانیے کا اسکیل"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"الارمز اور یاد دہانیاں"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"اس ایپ کو الارمز سیٹ کرنے اور وقت کے لحاظ سے حساس کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ اس سے ایپ کو پس منظر میں چلنے کی اجازت ملتی ہے، جس میں زیادہ بیٹری استعمال ہو سکتی ہے۔\n\n اگر یہ اجازت آف ہے تو موجودہ الارمز اور اس ایپ کے ذریعے شیڈول کردہ وقت پر مبنی ایونٹس کام نہیں کریں گے۔"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"شیڈول، الارم، یاد دہانی، گھڑی"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"ڈسٹرب نہ کریں"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"آن کریں"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ڈسٹرب نہ کریں\' کو آن کریں"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"کبھی نہیں"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"مدت"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ہر بار پوچھیں"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"یہاں تک کہ آپ آف کر دیں"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(کوئی نام نہیں)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"ابھی ابھی"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"یہ فون"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"یہ ٹیبلیٹ"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index f285086..93ffac8 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Grafik protsessorni tuzatish qatlamlarini yuklashni yoqish"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Taʼminotchining batafsil jurnali"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xatoliklar hisobotiga shaxsiy maʼlumotlari bor va koʻp joy olishi mumkin boʻlgan qurilma haqida taʼminotchining qoʻshimcha yozuvlari kiradi. Bunda batareya quvvati tezroq sarflanishi mumkin."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Oynalar animatsiyasi"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"O‘tish animatsiyasi"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatsiya tezligi"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signal va eslatmalar"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu ilovaga signal oʻrnatish va vaqtga asoslangan amallarni rejalashtirishga ruxsat berish. Bunda ilovaga orqa fonda ishlashiga imkon beriladi, shu sababli batareya ortiqcha sarflanishi mumkin.\n\nAgar bu ruxsat oʻchirilsa, ushbu ilova tomonidan rejalashtirilgan mavjud signallar va vaqtga asoslangan tadbirlar ishlamaydi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"reja, signal, eslatma, soat"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Bezovta qilinmasin"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Yoqish"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bezovta qilinmasin rejimini yoqing"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hech qachon"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Davomiyligi"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Har safar so‘ralsin"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Rejimdan chiqilgunicha"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ismi koʻrsatilmagan)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Hozir"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Shu telefon"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Shu planshet"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 9bb4ef5..414ad37 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Cho phép tải lớp gỡ lỗi GPU cho ứng dụng gỡ lỗi"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Bật tùy chọn ghi nhật ký chi tiết của nhà cung cấp"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Đưa thêm nhật ký của nhà cung cấp dành riêng cho thiết bị vào các báo cáo lỗi. Nhật ký này có thể chứa thông tin cá nhân, dùng nhiều pin hơn và/hoặc chiếm nhiều dung lượng lưu trữ hơn."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Tỷ lệ hình động của cửa sổ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Tỷ lệ hình động chuyển tiếp"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Tỷ lệ thời lượng của trình tạo hình động"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Chuông báo và lời nhắc"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Cho phép ứng dụng này đặt chuông báo và lên lịch các hành động cần chính xác về thời gian. Tùy chọn này cho phép ứng dụng chạy ở chế độ nền và có thể làm tiêu hao nhiều pin.\n\nNếu không cấp quyền này, các chuông báo và sự kiện theo thời gian do ứng dụng này lên lịch sẽ không hoạt động."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"lịch biểu, chuông báo, lời nhắc, đồng hồ"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Không làm phiền"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bật"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bật chế độ Không làm phiền"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Không bao giờ"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Thời lượng"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Luôn hỏi"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Cho đến khi bạn tắt"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Không có tên)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Vừa xong"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Điện thoại này"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Máy tính bảng này"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index c1d5481..c0a8f2d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允许为调试应用加载 GPU 调试层"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"启用详细供应商日志记录"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在 bug 报告中包含其他设备特定的供应商日志,这些日志可能会含有隐私信息、消耗更多电量和/或使用更多存储空间。"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"窗口动画缩放"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"过渡动画缩放"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 时长缩放"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"闹钟和提醒"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允许该应用设置闹钟以及安排在特定时间执行某些操作。这项权限开启后,该应用将在后台运行,可能会消耗更多电池电量。\n\n如果您关闭此权限,该应用设置的现有闹钟将不会响起,而且该应用安排在特定时间执行的现有活动也不会执行。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"设置, 闹钟, 提醒, 时钟, schedule, alarm, reminder, clock"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"勿扰模式"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"开启"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"开启勿扰模式"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"持续时间"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"每次都询问"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"直到您将其关闭"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(无姓名)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"刚刚"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"这部手机"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"这部平板电脑"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index d09a281..74f2678 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允許為偵錯應用程式載入 GPU 偵錯圖層"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"啟用詳細供應商記錄"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在錯誤報告中加入其他裝置專屬供應商記錄,其中可能包含私人資料,並會耗用更多電量及/或儲存空間。"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"視窗動畫比例"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 片長比例"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"鬧鐘和提醒"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許此應用程式設定鬧鐘及安排具時效性的操作。這讓應用程式在背景中執行,因此可能會較耗電。\n\n如果關閉此權限,此應用程式將不會在預定時間響起已設定的鬧鐘,亦不會就特定時間的活動傳送通知。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"日程表, 鬧鐘, 提醒, 時鐘"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"請勿騷擾"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「請勿騷擾」模式"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"持續時間"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"每次都詢問"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"直至你關閉為止"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(沒有名稱)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"此手機"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"此平板電腦"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index fdb4cf3..5b068e3 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允許載入 GPU 偵錯圖層為應用程式偵錯"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"啟用詳細供應商記錄功能"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在錯誤報告中附上其他的裝置專屬供應商記錄。如果你這麼做,可能會增加電池用量及/或占用較多儲存空間,報告中可能也會包含私人資訊。"</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"視窗動畫比例"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"動畫影片長度比例"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"鬧鐘和提醒"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許這個應用程式設定鬧鐘及安排有時效性的動作。之後應用程式可以在背景執行,並可能耗用較多電量。\n\n如果關閉這項權限,這個應用程式設定的現有鬧鐘將不會響起,系統也無法在預定的時間發出活動提醒。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"時間表, 鬧鐘, 提醒, 時鐘"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"零打擾"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「零打擾」模式"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"時間長度"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"每次都詢問"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"直到你關閉為止"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(無顯示名稱)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"這支手機"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"這台平板電腦"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 0a0fdff..da152ce 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -408,6 +408,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Vumela izendlalelo zokususa amaphutha ze-GPU ngezinhlelo zokusebenza zokususa amaphutha"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Nika amandla ilogu yomthengisi we-verbose"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Faka phakathi amalogu athize womthengisi wedivayisi angeziwe, angase afake phakathi ulwazi oluyimfihlo, kusebenzisa ibhethri eningi, futhi/noma kusebenzisa isitoreji esiningi."</string>
+ <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+ <skip />
+ <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+ <skip />
<string name="window_animation_scale_title" msgid="5236381298376812508">"Iwindi yesilinganisi sesithombe esinyakazayo"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Isilinganiso sesithombe soku"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Isilinganiso sobude besikhathi somenzi womfanekiso onyakazayo"</string>
@@ -557,6 +569,7 @@
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ama-alamu nezikhumbuzi"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Vumela le app isethe ama-alamu futhi ushejule izenzo zesikhathi esizwelayo. Lokhu kuvumela i-app iqhubeke ngemuva okungasebenzisa ibhethri lakho eliningi.\n\nUma le mvume ivaliwe, ama-alamu asele nemicimbi esekelwe esikhathini ehlelwe yile app ngeke kusebenze."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ishejuli, i-alamu, isikhumbuzi, iwashi"</string>
+ <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ungaphazamisi"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vula"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vula ukungaphazamisi"</string>
<string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Soze"</string>
@@ -569,6 +582,7 @@
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Ubude besikhathi"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Buza njalo"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Uze uvale isikrini"</string>
+ <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Alikho igama)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Khona manje"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Le foni"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Le thebhulethi"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 27c386e..cfd74d4 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1010,10 +1010,10 @@
<!-- UI debug setting: force allow on external summary [CHAR LIMIT=150] -->
<string name="force_resizable_activities_summary">Make all activities resizable for multi-window, regardless of manifest values.</string>
- <!-- UI debug setting: enable freeform window support [CHAR LIMIT=50] -->
- <string name="enable_freeform_support">Enable freeform windows</string>
- <!-- UI debug setting: enable freeform window support summary [CHAR LIMIT=150] -->
- <string name="enable_freeform_support_summary">Enable support for experimental freeform windows.</string>
+ <!-- UI debug setting: enable legacy freeform window support [CHAR LIMIT=50] -->
+ <string name="enable_freeform_support">Enable freeform windows (legacy)</string>
+ <!-- UI debug setting: enable legacy freeform window support summary [CHAR LIMIT=150] -->
+ <string name="enable_freeform_support_summary">Enable support for experimental legacy freeform windows.</string>
<!-- Local (desktop) backup password menu title [CHAR LIMIT=25] -->
<string name="local_backup_password_title">Desktop backup password</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
index 7669e79b..f8c3a93 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
@@ -1,9 +1,4 @@
# Default reviewers for this and subdirectories.
-siyuanh@google.com
-hughchen@google.com
-timhypeng@google.com
-robertluo@google.com
-songferngwang@google.com
yqian@google.com
chelseahao@google.com
yiyishen@google.com
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
index c5e86b4..4f2329b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
@@ -327,4 +327,12 @@
return sInstance;
}
}
+
+ /** Testing only. Reset the instance to avoid tests affecting each other. */
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ public static void resetInstance() {
+ synchronized (PowerAllowlistBackend.class) {
+ sInstance = null;
+ }
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
index df0e618..8868837 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
@@ -23,19 +23,8 @@
import android.telephony.UiccSlotInfo;
import android.telephony.UiccSlotMapping;
-import java.util.List;
-
public class DataServiceUtils {
- public static <T> boolean shouldUpdateEntityList(List<T> oldList, List<T> newList) {
- if ((oldList != null &&
- (newList.isEmpty() || !newList.equals(oldList)))
- || (!newList.isEmpty() && oldList == null)) {
- return true;
- }
- return false;
- }
-
/**
* Represents columns of the MobileNetworkInfoData table, define these columns from
* {@see MobileNetworkUtils} or relevant common APIs.
@@ -52,73 +41,16 @@
public static final String COLUMN_ID = "subId";
/**
- * The name of the contact discovery enabled state column,
- * {@see MobileNetworkUtils#isContactDiscoveryEnabled(Context, int)}.
- */
- public static final String COLUMN_IS_CONTACT_DISCOVERY_ENABLED =
- "isContactDiscoveryEnabled";
-
- /**
- * The name of the contact discovery visible state column,
- * {@see MobileNetworkUtils#isContactDiscoveryEnabled(Context, int)}.
- */
- public static final String COLUMN_IS_CONTACT_DISCOVERY_VISIBLE =
- "isContactDiscoveryVisible";
-
- /**
* The name of the mobile network data state column,
* {@see MobileNetworkUtils#isMobileDataEnabled(Context)}.
*/
public static final String COLUMN_IS_MOBILE_DATA_ENABLED = "isMobileDataEnabled";
/**
- * The name of the CDMA option state column,
- * {@see MobileNetworkUtils#isCdmaOptions(Context, int)}.
- */
- public static final String COLUMN_IS_CDMA_OPTIONS = "isCdmaOptions";
-
- /**
- * The name of the GSM option state column,
- * {@see MobileNetworkUtils#isGsmOptions(Context, int)}.
- */
- public static final String COLUMN_IS_GSM_OPTIONS = "isGsmOptions";
-
- /**
- * The name of the world mode state column,
- * {@see MobileNetworkUtils#isWorldMode(Context, int)}.
- */
- public static final String COLUMN_IS_WORLD_MODE = "isWorldMode";
-
- /**
- * The name of the display network select options state column,
- * {@see MobileNetworkUtils#shouldDisplayNetworkSelectOptions(Context, int)}.
- */
- public static final String COLUMN_SHOULD_DISPLAY_NETWORK_SELECT_OPTIONS =
- "shouldDisplayNetworkSelectOptions";
-
- /**
- * The name of the TDSCDMA supported state column,
- * {@see MobileNetworkUtils#isTdscdmaSupported(Context, int)}.
- */
- public static final String COLUMN_IS_TDSCDMA_SUPPORTED = "isTdscdmaSupported";
-
- /**
- * The name of the active network is cellular state column,
- * {@see MobileNetworkUtils#activeNetworkIsCellular(Context)}.
- */
- public static final String COLUMN_ACTIVE_NETWORK_IS_CELLULAR = "activeNetworkIsCellular";
-
- /**
* The name of the show toggle for physicalSim state column,
* {@see SubscriptionUtil#showToggleForPhysicalSim(SubscriptionManager)}.
*/
public static final String COLUMN_SHOW_TOGGLE_FOR_PHYSICAL_SIM = "showToggleForPhysicalSim";
-
- /**
- * The name of the subscription's data roaming state column,
- * {@see TelephonyManager#isDataRoamingEnabled()}.
- */
- public static final String COLUMN_IS_DATA_ROAMING_ENABLED = "isDataRoamingEnabled";
}
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
index e72346d..13f99e9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
@@ -26,23 +26,11 @@
@Entity(tableName = DataServiceUtils.MobileNetworkInfoData.TABLE_NAME)
public class MobileNetworkInfoEntity {
- public MobileNetworkInfoEntity(@NonNull String subId, boolean isContactDiscoveryEnabled,
- boolean isContactDiscoveryVisible, boolean isMobileDataEnabled, boolean isCdmaOptions,
- boolean isGsmOptions, boolean isWorldMode, boolean shouldDisplayNetworkSelectOptions,
- boolean isTdscdmaSupported, boolean activeNetworkIsCellular,
- boolean showToggleForPhysicalSim, boolean isDataRoamingEnabled) {
+ public MobileNetworkInfoEntity(@NonNull String subId, boolean isMobileDataEnabled,
+ boolean showToggleForPhysicalSim) {
this.subId = subId;
- this.isContactDiscoveryEnabled = isContactDiscoveryEnabled;
- this.isContactDiscoveryVisible = isContactDiscoveryVisible;
this.isMobileDataEnabled = isMobileDataEnabled;
- this.isCdmaOptions = isCdmaOptions;
- this.isGsmOptions = isGsmOptions;
- this.isWorldMode = isWorldMode;
- this.shouldDisplayNetworkSelectOptions = shouldDisplayNetworkSelectOptions;
- this.isTdscdmaSupported = isTdscdmaSupported;
- this.activeNetworkIsCellular = activeNetworkIsCellular;
this.showToggleForPhysicalSim = showToggleForPhysicalSim;
- this.isDataRoamingEnabled = isDataRoamingEnabled;
}
@PrimaryKey
@@ -50,55 +38,18 @@
@NonNull
public String subId;
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_CONTACT_DISCOVERY_ENABLED)
- public boolean isContactDiscoveryEnabled;
-
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_CONTACT_DISCOVERY_VISIBLE)
- public boolean isContactDiscoveryVisible;
-
@ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_MOBILE_DATA_ENABLED)
public boolean isMobileDataEnabled;
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_CDMA_OPTIONS)
- public boolean isCdmaOptions;
-
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_GSM_OPTIONS)
- public boolean isGsmOptions;
-
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_WORLD_MODE)
- public boolean isWorldMode;
-
- @ColumnInfo(name =
- DataServiceUtils.MobileNetworkInfoData.COLUMN_SHOULD_DISPLAY_NETWORK_SELECT_OPTIONS)
- public boolean shouldDisplayNetworkSelectOptions;
-
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_TDSCDMA_SUPPORTED)
- public boolean isTdscdmaSupported;
-
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_ACTIVE_NETWORK_IS_CELLULAR)
- public boolean activeNetworkIsCellular;
-
@ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_SHOW_TOGGLE_FOR_PHYSICAL_SIM)
public boolean showToggleForPhysicalSim;
- @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_DATA_ROAMING_ENABLED)
- public boolean isDataRoamingEnabled;
-
@Override
public int hashCode() {
int result = 17;
result = 31 * result + subId.hashCode();
- result = 31 * result + Boolean.hashCode(isContactDiscoveryEnabled);
- result = 31 * result + Boolean.hashCode(isContactDiscoveryVisible);
result = 31 * result + Boolean.hashCode(isMobileDataEnabled);
- result = 31 * result + Boolean.hashCode(isCdmaOptions);
- result = 31 * result + Boolean.hashCode(isGsmOptions);
- result = 31 * result + Boolean.hashCode(isWorldMode);
- result = 31 * result + Boolean.hashCode(shouldDisplayNetworkSelectOptions);
- result = 31 * result + Boolean.hashCode(isTdscdmaSupported);
- result = 31 * result + Boolean.hashCode(activeNetworkIsCellular);
result = 31 * result + Boolean.hashCode(showToggleForPhysicalSim);
- result = 31 * result + Boolean.hashCode(isDataRoamingEnabled);
return result;
}
@@ -113,45 +64,18 @@
MobileNetworkInfoEntity info = (MobileNetworkInfoEntity) obj;
return TextUtils.equals(subId, info.subId)
- && isContactDiscoveryEnabled == info.isContactDiscoveryEnabled
- && isContactDiscoveryVisible == info.isContactDiscoveryVisible
&& isMobileDataEnabled == info.isMobileDataEnabled
- && isCdmaOptions == info.isCdmaOptions
- && isGsmOptions == info.isGsmOptions
- && isWorldMode == info.isWorldMode
- && shouldDisplayNetworkSelectOptions == info.shouldDisplayNetworkSelectOptions
- && isTdscdmaSupported == info.isTdscdmaSupported
- && activeNetworkIsCellular == info.activeNetworkIsCellular
- && showToggleForPhysicalSim == info.showToggleForPhysicalSim
- && isDataRoamingEnabled == info.isDataRoamingEnabled;
+ && showToggleForPhysicalSim == info.showToggleForPhysicalSim;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(" {MobileNetworkInfoEntity(subId = ")
.append(subId)
- .append(", isContactDiscoveryEnabled = ")
- .append(isContactDiscoveryEnabled)
- .append(", isContactDiscoveryVisible = ")
- .append(isContactDiscoveryVisible)
.append(", isMobileDataEnabled = ")
.append(isMobileDataEnabled)
- .append(", isCdmaOptions = ")
- .append(isCdmaOptions)
- .append(", isGsmOptions = ")
- .append(isGsmOptions)
- .append(", isWorldMode = ")
- .append(isWorldMode)
- .append(", shouldDisplayNetworkSelectOptions = ")
- .append(shouldDisplayNetworkSelectOptions)
- .append(", isTdscdmaSupported = ")
- .append(isTdscdmaSupported)
.append(", activeNetworkIsCellular = ")
- .append(activeNetworkIsCellular)
- .append(", showToggleForPhysicalSim = ")
.append(showToggleForPhysicalSim)
- .append(", isDataRoamingEnabled = ")
- .append(isDataRoamingEnabled)
.append(")}");
return builder.toString();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
index 3f19830..960df63 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
@@ -20,6 +20,7 @@
import static java.util.Objects.requireNonNull;
+import android.annotation.DrawableRes;
import android.annotation.Nullable;
import android.app.AutomaticZenRule;
import android.content.Context;
@@ -120,7 +121,14 @@
}
private static Drawable getFallbackIcon(Context context, int ruleType) {
- int iconResIdFromType = switch (ruleType) {
+ int iconResIdFromType = getIconResourceIdFromType(ruleType);
+ return requireNonNull(context.getDrawable(iconResIdFromType));
+ }
+
+ /** Return the default icon resource associated to a {@link AutomaticZenRule.Type} */
+ @DrawableRes
+ public static int getIconResourceIdFromType(@AutomaticZenRule.Type int ruleType) {
+ return switch (ruleType) {
case AutomaticZenRule.TYPE_UNKNOWN ->
com.android.internal.R.drawable.ic_zen_mode_type_unknown;
case AutomaticZenRule.TYPE_OTHER ->
@@ -141,7 +149,6 @@
com.android.internal.R.drawable.ic_zen_mode_type_managed;
default -> com.android.internal.R.drawable.ic_zen_mode_type_unknown;
};
- return requireNonNull(context.getDrawable(iconResIdFromType));
}
private static Drawable getMonochromeIconIfPresent(Drawable icon) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
index 33d39f0..2cc9112 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
@@ -23,6 +23,7 @@
import static android.service.notification.ZenModeConfig.tryParseEventConditionId;
import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
@@ -33,12 +34,15 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.service.notification.SystemZenRules;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log;
+import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -56,11 +60,12 @@
* <p>It also adapts other rule features that we don't want to expose in the UI, such as
* interruption filters other than {@code PRIORITY}, rules without specific icons, etc.
*/
-public class ZenMode {
+public class ZenMode implements Parcelable {
private static final String TAG = "ZenMode";
static final String MANUAL_DND_MODE_ID = "manual_dnd";
+ static final String TEMP_NEW_MODE_ID = "temp_new_mode";
// Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy.
private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALARMS =
@@ -125,6 +130,25 @@
isActive ? Status.ENABLED_AND_ACTIVE : Status.ENABLED, true);
}
+ /**
+ * Returns a new {@link ZenMode} instance that can represent a custom_manual mode that is in the
+ * process of being created (and not yet saved).
+ *
+ * @param name mode name
+ * @param iconResId resource id of the chosen icon, {code 0} if none.
+ */
+ public static ZenMode newCustomManual(String name, @DrawableRes int iconResId) {
+ AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
+ ZenModeConfig.toCustomManualConditionId())
+ .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
+ .setType(AutomaticZenRule.TYPE_OTHER)
+ .setOwner(ZenModeConfig.getCustomManualConditionProvider())
+ .setIconResId(iconResId)
+ .setManualInvocationAllowed(true)
+ .build();
+ return new ZenMode(TEMP_NEW_MODE_ID, rule, Status.ENABLED, false);
+ }
+
private ZenMode(String id, @NonNull AutomaticZenRule rule, Status status, boolean isManualDnd) {
mId = id;
mRule = rule;
@@ -304,4 +328,34 @@
public String toString() {
return mId + " (" + mStatus + ") -> " + mRule;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mId);
+ dest.writeParcelable(mRule, 0);
+ dest.writeString(mStatus.name());
+ dest.writeBoolean(mIsManualDnd);
+ }
+
+ public static final Creator<ZenMode> CREATOR = new Creator<ZenMode>() {
+ @Override
+ public ZenMode createFromParcel(Parcel in) {
+ return new ZenMode(
+ in.readString(),
+ checkNotNull(in.readParcelable(AutomaticZenRule.class.getClassLoader(),
+ AutomaticZenRule.class)),
+ Status.valueOf(in.readString()),
+ in.readBoolean());
+ }
+
+ @Override
+ public ZenMode[] newArray(int size) {
+ return new ZenMode[size];
+ }
+ };
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
index 5529da0..d36e2fe 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
@@ -27,6 +27,8 @@
import android.service.notification.ZenModeConfig;
import android.util.Log;
+import androidx.annotation.DrawableRes;
+
import com.android.settingslib.R;
import java.time.Duration;
@@ -184,18 +186,13 @@
* Creates a new custom mode with the provided {@code name}. The mode will be "manual" (i.e.
* not have a schedule), this can be later updated by the user in the mode settings page.
*
+ * @param name mode name
+ * @param iconResId resource id of the chosen icon, {code 0} if none.
* @return the created mode. Only {@code null} if creation failed due to an internal error
*/
@Nullable
- public ZenMode addCustomMode(String name) {
- AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
- ZenModeConfig.toCustomManualConditionId())
- .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
- .setType(AutomaticZenRule.TYPE_OTHER)
- .setOwner(ZenModeConfig.getCustomManualConditionProvider())
- .setManualInvocationAllowed(true)
- .build();
-
+ public ZenMode addCustomManualMode(String name, @DrawableRes int iconResId) {
+ AutomaticZenRule rule = ZenMode.newCustomManual(name, iconResId).getRule();
String ruleId = mNotificationManager.addAutomaticZenRule(rule);
return getMode(ruleId);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
index 8ec5ba1..c88c4c9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
@@ -46,6 +46,7 @@
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -98,6 +99,7 @@
private val contentResolver: ContentResolver,
private val backgroundCoroutineContext: CoroutineContext,
private val coroutineScope: CoroutineScope,
+ private val logger: Logger,
) : AudioRepository {
private val streamSettingNames: Map<AudioStream, String> =
@@ -170,6 +172,7 @@
.conflate()
.map { getCurrentAudioStream(audioStream) }
.onStart { emit(getCurrentAudioStream(audioStream)) }
+ .onEach { logger.onVolumeUpdateReceived(audioStream, it) }
.flowOn(backgroundCoroutineContext)
}
@@ -179,7 +182,7 @@
minVolume = getMinVolume(audioStream),
maxVolume = audioManager.getStreamMaxVolume(audioStream.value),
volume = audioManager.getStreamVolume(audioStream.value),
- isAffectedByMute = audioManager.isStreamAffectedByMute(audioStream.value),
+ isAffectedByMute = audioManager.isStreamMutableByUi(audioStream.value),
isAffectedByRingerMode = audioManager.isStreamAffectedByRingerMode(audioStream.value),
isMuted = audioManager.isStreamMute(audioStream.value),
)
@@ -193,6 +196,7 @@
override suspend fun setVolume(audioStream: AudioStream, volume: Int) {
withContext(backgroundCoroutineContext) {
+ logger.onSetVolumeRequested(audioStream, volume)
audioManager.setStreamVolume(audioStream.value, volume, 0)
}
}
@@ -247,4 +251,11 @@
awaitClose { contentResolver.unregisterContentObserver(observer) }
}
}
+
+ interface Logger {
+
+ fun onSetVolumeRequested(audioStream: AudioStream, volume: Int)
+
+ fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel)
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt b/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt
index 9c48299..c8e4d71 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt
@@ -17,6 +17,7 @@
package com.android.settingslib.volume.shared.model
import android.media.AudioManager
+import android.media.AudioSystem
/** Type-safe wrapper for [AudioManager] audio stream. */
@JvmInline
@@ -25,6 +26,8 @@
require(value in supportedStreamTypes) { "Unsupported stream=$value" }
}
+ override fun toString(): String = AudioSystem.streamToString(value)
+
companion object {
val supportedStreamTypes =
setOf(
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
index 727c61c..a7e0464 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
@@ -498,7 +498,7 @@
): Job =
coroutineScope.launch {
val wifiManager = context.getSystemService(WifiManager::class.java) ?: return@launch
- if (wifiManager.queryWepAllowed()) {
+ if (wifiManager.isWepSupported == true && wifiManager.queryWepAllowed()) {
onAllowed()
} else {
val intent = Intent(Intent.ACTION_MAIN).apply {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
index 844dc12..0e43acb 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
@@ -64,6 +64,7 @@
@Mock private lateinit var communicationDevice: AudioDeviceInfo
@Mock private lateinit var contentResolver: ContentResolver
+ private val logger = FakeAudioRepositoryLogger()
private val eventsReceiver = FakeAudioManagerEventsReceiver()
private val volumeByStream: MutableMap<Int, Int> = mutableMapOf()
private val isAffectedByRingerModeByStream: MutableMap<Int, Boolean> = mutableMapOf()
@@ -109,6 +110,7 @@
contentResolver,
testScope.testScheduler,
testScope.backgroundScope,
+ logger,
)
}
@@ -173,6 +175,15 @@
underTest.setVolume(audioStream, 50)
runCurrent()
+ assertThat(logger.logs)
+ .isEqualTo(
+ listOf(
+ "onVolumeUpdateReceived audioStream=STREAM_SYSTEM",
+ "onSetVolumeRequested audioStream=STREAM_SYSTEM",
+ "onVolumeUpdateReceived audioStream=STREAM_SYSTEM",
+ "onVolumeUpdateReceived audioStream=STREAM_SYSTEM",
+ )
+ )
assertThat(streamModel)
.isEqualTo(
AudioStreamModel(
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt
new file mode 100644
index 0000000..389bf53
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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.settingslib.volume.data.repository
+
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.settingslib.volume.shared.model.AudioStreamModel
+
+class FakeAudioRepositoryLogger : AudioRepositoryImpl.Logger {
+
+ private val mutableLogs: MutableList<String> = mutableListOf()
+ val logs: List<String>
+ get() = mutableLogs
+
+ override fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) {
+ synchronized(mutableLogs) {
+ mutableLogs.add("onSetVolumeRequested audioStream=$audioStream")
+ }
+ }
+
+ override fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel) {
+ synchronized(mutableLogs) {
+ mutableLogs.add("onVolumeUpdateReceived audioStream=$audioStream")
+ }
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
index 32cdb98..9e54312 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
@@ -21,13 +21,17 @@
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.app.AutomaticZenRule;
import android.net.Uri;
+import android.os.Parcel;
import android.service.notification.Condition;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
+import com.android.internal.R;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -161,6 +165,30 @@
assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
}
+ @Test
+ public void writeToParcel_equals() {
+ assertUnparceledIsEqualToOriginal("example",
+ new ZenMode("id", ZEN_RULE, zenConfigRuleFor(ZEN_RULE, false)));
+
+ assertUnparceledIsEqualToOriginal("dnd", ZenMode.manualDndMode(ZEN_RULE, true));
+
+ assertUnparceledIsEqualToOriginal("custom_manual",
+ ZenMode.newCustomManual("New mode", R.drawable.ic_zen_mode_type_immersive));
+ }
+
+ private static void assertUnparceledIsEqualToOriginal(String type, ZenMode original) {
+ Parcel parcel = Parcel.obtain();
+ try {
+ original.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ ZenMode unparceled = ZenMode.CREATOR.createFromParcel(parcel);
+
+ assertWithMessage("Comparing " + type).that(unparceled).isEqualTo(original);
+ } finally {
+ parcel.recycle();
+ }
+ }
+
private static ZenModeConfig.ZenRule zenConfigRuleFor(AutomaticZenRule azr, boolean isActive) {
ZenModeConfig.ZenRule zenRule = new ZenModeConfig.ZenRule();
zenRule.pkg = azr.getPackageName();
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 097840e..5ddf005 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -45,7 +45,7 @@
<integer name="def_location_mode">3</integer>
<!-- 0 == off, 1 == on-->
<integer name="def_paired_device_location_mode">1</integer>
- <bool name="assisted_gps_enabled">true</bool>
+ <bool name="assisted_gps_enabled">false</bool>
<bool name="def_netstats_enabled">true</bool>
<bool name="def_usb_mass_storage_enabled">true</bool>
<bool name="def_wifi_on">false</bool>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 8d02dbd..d4a4703 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -134,6 +134,7 @@
Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
Settings.Secure.ACTIVE_UNLOCK_ON_WAKE,
Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT,
+ Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY,
Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS,
Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 7169cf7..6df1c45 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -195,6 +195,7 @@
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_WAKE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS, ANY_STRING_VALIDATOR);
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, ANY_STRING_VALIDATOR);
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index d54236e..54f0d7a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1189,6 +1189,8 @@
synchronized (mLock) {
if (getSyncDisabledModeConfigLocked() != SYNC_DISABLED_MODE_NONE) {
+ Slog.v(LOG_TAG, "did not write settings for prefix '"
+ + prefix + "' because sync is disabled");
return SET_ALL_RESULT_DISABLED;
}
final int key = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 05eb044..861c405 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -203,6 +203,12 @@
private static final String NULL_VALUE = "null";
+ // TOBO(b/312444587): remove after Test Mission 2.
+ // Bulk sync names
+ private static final String BULK_SYNC_MARKER = "aconfigd_marker/bulk_synced";
+ private static final String BULK_SYNC_TRIGGER_COUNTER =
+ "core_experiments_team_internal/BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
+
private static final ArraySet<String> sSystemPackages = new ArraySet<>();
private final Object mWriteLock = new Object();
@@ -409,8 +415,7 @@
}
}
// TOBO(b/312444587): remove the comparison logic after Test Mission 2.
- if (mSettings.get("aconfigd_marker/bulk_synced").value.equals("true")
- && requests == null) {
+ if (requests == null) {
Map<String, AconfigdFlagInfo> aconfigdFlagMap =
AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket);
compareFlagValueInNewStorage(
@@ -534,7 +539,7 @@
return null;
}
AconfigdFlagInfo flag = flagInfoDefault.get(fullFlagName);
- if (flag == null) {
+ if (flag == null || !namespace.equals(flag.getNamespace())) {
return null;
}
@@ -553,15 +558,33 @@
public ProtoOutputStream handleBulkSyncToNewStorage(
Map<String, AconfigdFlagInfo> aconfigFlagMap) {
// get marker or add marker if it does not exist
- final String bulkSyncMarkerName = new String("aconfigd_marker/bulk_synced");
- Setting markerSetting = mSettings.get(bulkSyncMarkerName);
+ Setting markerSetting = mSettings.get(BULK_SYNC_MARKER);
+ int localCounter = 0;
if (markerSetting == null) {
- markerSetting = new Setting(bulkSyncMarkerName, "false", false, "aconfig", "aconfig");
- mSettings.put(bulkSyncMarkerName, markerSetting);
+ markerSetting = new Setting(BULK_SYNC_MARKER, "0", false, "aconfig", "aconfig");
+ mSettings.put(BULK_SYNC_MARKER, markerSetting);
+ }
+ try {
+ localCounter = Integer.parseInt(markerSetting.value);
+ } catch(NumberFormatException e) {
+ // reset local counter
+ markerSetting.value = "0";
}
if (enableAconfigStorageDaemon()) {
- if (markerSetting.value.equals("true")) {
+ Setting bulkSyncCounter = mSettings.get(BULK_SYNC_TRIGGER_COUNTER);
+ int serverCounter = 0;
+ if (bulkSyncCounter != null) {
+ try {
+ serverCounter = Integer.parseInt(bulkSyncCounter.value);
+ } catch (NumberFormatException e) {
+ // reset the local value of server counter
+ bulkSyncCounter.value = "0";
+ }
+ }
+
+ boolean shouldSync = localCounter < serverCounter;
+ if (!shouldSync) {
// CASE 1, flag is on, bulk sync marker true, nothing to do
return null;
} else {
@@ -600,20 +623,12 @@
}
// mark sync has been done
- markerSetting.value = "true";
+ markerSetting.value = String.valueOf(serverCounter);
scheduleWriteIfNeededLocked();
return requests;
}
} else {
- if (markerSetting.value.equals("true")) {
- // CASE 3, flag is off, bulk sync marker true, clear the marker
- markerSetting.value = "false";
- scheduleWriteIfNeededLocked();
- return null;
- } else {
- // CASE 4, flag is off, bulk sync marker false, nothing to do
- return null;
- }
+ return null;
}
}
@@ -692,6 +707,7 @@
.setFlagName(flag.getName())
.setDefaultFlagValue(flagValue)
.setIsReadWrite(isReadWrite)
+ .setNamespace(flag.getNamespace())
.build());
}
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 5f8e933..411decd 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -177,6 +177,7 @@
Settings.Global.DESK_UNDOCK_SOUND,
Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT,
Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+ Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
Settings.Global.DEVELOPMENT_FORCE_RTL,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 94aeb9b..4b4ced3 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -151,12 +151,14 @@
.setFlagName("flag1")
.setDefaultFlagValue("false")
.setIsReadWrite(true)
+ .setNamespace("test_namespace")
.build();
AconfigdFlagInfo flag2 = AconfigdFlagInfo.newBuilder()
.setPackageName("com.android.flags")
.setFlagName("flag2")
.setDefaultFlagValue("true")
.setIsReadWrite(false)
+ .setNamespace("test_namespace")
.build();
Map<String, AconfigdFlagInfo> flagInfoDefault = new HashMap<>();
@@ -1018,12 +1020,17 @@
.setFlagName("flag1")
.setDefaultFlagValue("false")
.setIsReadWrite(true)
+ .setNamespace("test_namespace")
.build();
flagInfoDefault.put(flag1.getFullFlagName(), flag1);
- // server override
+ // not the right namespace
+ assertNull(
+ settingsState.getFlagOverrideToSync(
+ "some_namespace/com.android.flags.flag1", "true", flagInfoDefault));
+ // server override
settingsState.getFlagOverrideToSync(
"test_namespace/com.android.flags.flag1", "true", flagInfoDefault);
assertEquals("com.android.flags", flag1.getPackageName());
@@ -1079,21 +1086,45 @@
.setIsReadWrite(false)
.build());
+ String bulkSyncMarker = "aconfigd_marker/bulk_synced";
+ String bulkSyncCounter =
+ "core_experiments_team_internal/" +
+ "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
+
synchronized (lock) {
- settingsState.insertSettingLocked(
- "aconfigd_marker/bulk_synced", "false", null, false, "aconfig");
+ settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig");
+ settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
+ "com.google.android.platform.core_experiments_team_internal");
// first bulk sync
ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags);
assertTrue(requests != null);
String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("true", value);
+ assertEquals("1", value);
// send time should no longer bulk sync
requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertTrue(requests == null);
+ assertNull(requests);
value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("true", value);
+ assertEquals("1", value);
+
+ // won't sync if the marker is string
+ settingsState.insertSettingLocked(bulkSyncMarker, "true", null, false, "aconfig");
+ settingsState.insertSettingLocked(bulkSyncCounter, "0", null, false,
+ "com.google.android.platform.core_experiments_team_internal");
+ requests = settingsState.handleBulkSyncToNewStorage(flags);
+ assertNull(requests);
+ value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
+ assertEquals("0", value);
+
+ // won't sync if the marker and counter value are the same
+ settingsState.insertSettingLocked(bulkSyncMarker, "1", null, false, "aconfig");
+ settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
+ "com.google.android.platform.core_experiments_team_internal");
+ requests = settingsState.handleBulkSyncToNewStorage(flags);
+ assertNull(requests);
+ value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
+ assertEquals("1", value);
}
}
@@ -1107,21 +1138,34 @@
SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
Map<String, AconfigdFlagInfo> flags = new HashMap<>();
+ String bulkSyncMarker = "aconfigd_marker/bulk_synced";
+ String bulkSyncCounter =
+ "core_experiments_team_internal/" +
+ "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
synchronized (lock) {
settingsState.insertSettingLocked("aconfigd_marker/bulk_synced",
"true", null, false, "aconfig");
// when aconfigd is off, should change the marker to false
ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertTrue(requests == null);
+ assertNull(requests);
String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("false", value);
+ assertEquals("0", value);
// marker started with false value, after call, it should remain false
requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertTrue(requests == null);
+ assertNull(requests);
value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("false", value);
+ assertEquals("0", value);
+
+ // won't sync
+ settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig");
+ settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
+ "com.google.android.platform.core_experiments_team_internal");
+ requests = settingsState.handleBulkSyncToNewStorage(flags);
+ assertNull(requests);
+ value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
+ assertEquals("0", value);
}
}
@@ -1164,6 +1208,7 @@
.setFlagName("flag1")
.setDefaultFlagValue("false")
.setIsReadWrite(true)
+ .setNamespace("test_namespace")
.build();
flagInfoDefault.put(flag1.getFullFlagName(), flag1);
@@ -1186,6 +1231,7 @@
.setFlagName("flag2")
.setDefaultFlagValue("false")
.setIsReadWrite(true)
+ .setNamespace("test_namespace")
.build();
flagInfoDefault.put(flag2.getFullFlagName(), flag2);
synchronized (lock) {
@@ -1207,6 +1253,7 @@
.setFlagName("flag3")
.setDefaultFlagValue("false")
.setIsReadWrite(false)
+ .setNamespace("test_namespace")
.build();
flagInfoDefault.put(flag3.getFullFlagName(), flag3);
synchronized (lock) {
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
index 46c847b..f4a3a50 100644
--- a/packages/Shell/res/values-fa/strings.xml
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -24,10 +24,10 @@
<string name="bugreport_updating_wait" msgid="3322151947853929470">"لطفاً منتظر بمانید..."</string>
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"گزارش مشکل بهزودی در تلفن نشان داده میشود"</string>
<string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"برای همرسانی گزارش اشکالتان، انتخاب کنید"</string>
- <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"برای همرسانی گزارش اشکال، ضربه بزنید"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"برای همرسانی گزارش اشکال، تکضرب بزنید"</string>
<string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"انتخاب کنید تا گزارش اشکالتان بدون نماگرفت به اشتراک گذاشته شود یا منتظر بمانید گرفتن عکس از صفحهنمایش تمام شود"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"برای همرسانی گزارش مشکل بدون نماگرفت، ضربه بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
- <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"برای همرسانی گزارش مشکل بدون نماگرفت، ضربه بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"برای همرسانی گزارش مشکل بدون نماگرفت، تکضرب بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"برای همرسانی گزارش مشکل بدون نماگرفت، تکضرب بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"گزارشهای اشکال حاوی دادههایی از فایلهای مختلف گزارش سیستم هستند، که ممکن است حاوی دادههای حساس شما (از قبیل دادههای استفاده از برنامه و مکان) باشند. گزارشهای اشکال را فقط با افراد و برنامههایی که به آنها اعتماد دارید بهاشتراک بگذارید."</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"دوباره نشان داده نشود"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"گزارش اشکال"</string>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
index ce39385..876bd9d 100644
--- a/packages/Shell/res/values-nb/strings.xml
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -25,9 +25,9 @@
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Feilrapporten vises snart på telefonen"</string>
<string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Velg for å dele feilrapporten"</string>
<string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Trykk for å dele feilrapporten"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Velg for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string>
- <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Velg for å dele feilrapporten uten noen skjermbilde, eller vent til skjermbildet er klar"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermbilde, eller vent til skjermbildet er klar"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermbilde, eller vent til skjermbildet er klar"</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"Feilrapporter inneholder data fra systemets forskjellige loggfiler. Dette kan inkludere data du ser på som sensitiv (for eksempel appbruk og posisjonsdata). Du bør bare dele feilrapporter med folk og apper du stoler på."</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ikke vis igjen"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"Feilrapporter"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index bd7c9a0..b5776e2 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -193,7 +193,7 @@
"tests/src/**/systemui/media/dialog/MediaOutputDialogTest.java",
"tests/src/**/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt",
"tests/src/**/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt",
- "tests/src/**/systemui/navigationbar/NavigationBarButtonTest.java",
+ "tests/src/**/systemui/navigationbar/views/NavigationBarButtonTest.java",
"tests/src/**/systemui/people/PeopleProviderTest.java",
"tests/src/**/systemui/people/PeopleSpaceUtilsTest.java",
"tests/src/**/systemui/people/widget/PeopleSpaceWidgetManagerTest.java",
@@ -449,7 +449,7 @@
"tests/src/**/systemui/doze/DozeScreenStateTest.java",
"tests/src/**/systemui/keyguard/WorkLockActivityControllerTest.java",
"tests/src/**/systemui/media/dialog/MediaOutputControllerTest.java",
- "tests/src/**/systemui/navigationbar/NavigationBarTest.java",
+ "tests/src/**/systemui/navigationbar/views/NavigationBarTest.java",
"tests/src/**/systemui/power/PowerNotificationWarningsTest.java",
"tests/src/**/systemui/power/PowerUITest.java",
"tests/src/**/systemui/qs/QSFooterViewControllerTest.java",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b37db16..666d939 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -280,6 +280,9 @@
<!-- to adjust volume in volume panel -->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <!-- to get bluetooth audio device category -->
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED" />
+
<!-- to access ResolverRankerServices -->
<uses-permission android:name="android.permission.BIND_RESOLVER_RANKER_SERVICE" />
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index e03ac3d..795b395 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -8,6 +8,7 @@
acul@google.com
adamcohen@google.com
aioana@google.com
+alexchau@google.com
alexflo@google.com
andonian@google.com
amiko@google.com
@@ -89,8 +90,10 @@
rgl@google.com
roosa@google.com
saff@google.com
+samcackett@google.com
santie@google.com
shanh@google.com
+silvajordan@google.com
snoeberger@google.com
spdonghao@google.com
steell@google.com
@@ -103,6 +106,7 @@
tracyzhou@google.com
tsuji@google.com
twickham@google.com
+uwaisashraf@google.com
vadimt@google.com
valiiftime@google.com
vanjan@google.com
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
index a3e7ab0..0983052 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
@@ -2,7 +2,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="accessibility_menu_service_name" msgid="730136711554740131">"Tilgjengelighetsmeny"</string>
- <string name="accessibility_menu_intro" msgid="3164193281544042394">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermdumper med mer."</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermbilder med mer."</string>
<string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
<string name="assistant_utterance" msgid="65509599221141377">"Assistent"</string>
<string name="a11y_settings_label" msgid="3977714687248445050">"Tilgjengelighetsinnstillinger"</string>
@@ -13,14 +13,14 @@
<string name="quick_settings_label" msgid="2999117381487601865">"Hurtiginnstillinger"</string>
<string name="notifications_label" msgid="6829741046963013567">"Varsler"</string>
<string name="screenshot_label" msgid="863978141223970162">"Skjermdump"</string>
- <string name="screenshot_utterance" msgid="1430760563401895074">"Ta skjermdump"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ta skjermbilde"</string>
<string name="volume_up_label" msgid="8592766918780362870">"Volum opp"</string>
<string name="volume_down_label" msgid="8574981863656447346">"Volum ned"</string>
<string name="brightness_up_label" msgid="8010753822854544846">"Lysstyrke opp"</string>
<string name="brightness_down_label" msgid="7115662941913272072">"Lysstyrke ned"</string>
<string name="previous_button_content_description" msgid="840869171117765966">"Gå til forrige skjerm"</string>
<string name="next_button_content_description" msgid="6810058269847364406">"Gå til neste skjerm"</string>
- <string name="accessibility_menu_description" msgid="4458354794093858297">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermdumper med mer."</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermbilder med mer."</string>
<string name="accessibility_menu_summary" msgid="340071398148208130">"Kontroller enheten med en stor meny"</string>
<string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Innstillinger for Tilgjengelighetsmeny"</string>
<string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Store knapper"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 90885ab..18fbf77 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -146,6 +146,16 @@
}
flag {
+ name: "notification_transparent_header_fix"
+ namespace: "systemui"
+ description: "fix the transparent group header issue for async header inflation."
+ bug: "340161724"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "pss_app_selector_abrupt_exit_fix"
namespace: "systemui"
description: "Fixes the app selector abruptly disappearing without an animation, when the"
@@ -217,6 +227,17 @@
}
flag {
+ name: "notification_group_hun_removal_animation_fix"
+ namespace: "systemui"
+ description: "Fix the lack of hun removal animation for group notifications"
+ "(not GROUP_ALERT_SUMMARY)"
+ bug: "343475993"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "scene_container"
namespace: "systemui"
description: "Enables the scene container framework go/flexiglass."
@@ -513,6 +534,16 @@
}
flag {
+ name: "use_volume_controller"
+ namespace: "systemui"
+ description: "Adds Volume Controller signals to the AudioRepository to update volume"
+ bug: "349348461"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "screenshot_action_dismiss_system_windows"
namespace: "systemui"
description: "Dismiss existing system windows when starting action from screenshot UI"
@@ -1021,13 +1052,6 @@
}
flag {
- name: "glanceable_hub_shortcut_button"
- namespace: "systemui"
- description: "Shows a button over the dream and lock screen to open the glanceable hub"
- bug: "339667383"
-}
-
-flag {
name: "glanceable_hub_gesture_handle"
namespace: "systemui"
description: "Shows a vertical bar at the right edge to indicate the user can swipe to open the glanceable hub"
@@ -1041,14 +1065,6 @@
bug: "343505271"
}
-
-flag {
- name: "new_touchpad_gestures_tutorial"
- namespace: "systemui"
- description: "Enables new interactive tutorial for learning touchpad gestures"
- bug: "309928033"
-}
-
flag {
name: "register_wallpaper_notifier_background"
namespace: "systemui"
@@ -1118,3 +1134,13 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "translucent_occluding_activity_fix"
+ namespace: "systemui"
+ description: "Fixes occlusion animation for transluent activities"
+ bug: "303010980"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index b6e4e9b..c14ee62 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -22,6 +22,7 @@
import android.app.TaskInfo
import android.app.WindowConfiguration
import android.content.ComponentName
+import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Rect
import android.graphics.RectF
@@ -53,6 +54,7 @@
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.systemui.Flags.activityTransitionUseLargestWindow
+import com.android.systemui.Flags.translucentOccludingActivityFix
import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary
import com.android.wm.shell.shared.IShellTransitions
import com.android.wm.shell.shared.ShellTransitions
@@ -991,7 +993,12 @@
controller.createAnimatorState()
}
val windowBackgroundColor =
- window.taskInfo?.let { callback.getBackgroundColor(it) } ?: window.backgroundColor
+ if (translucentOccludingActivityFix() && window.isTranslucent) {
+ Color.TRANSPARENT
+ } else {
+ window.taskInfo?.let { callback.getBackgroundColor(it) }
+ ?: window.backgroundColor
+ }
// TODO(b/184121838): We should somehow get the top and bottom radius of the window
// instead of recomputing isExpandingFullyAbove here.
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 2ed0f6c..bb76c1d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -155,12 +155,12 @@
val coroutineScope = rememberCoroutineScope()
val currentSceneKey: SceneKey by
viewModel.currentScene.collectAsStateWithLifecycle(CommunalScenes.Blank)
- val touchesAllowed by viewModel.touchesAllowed.collectAsStateWithLifecycle(initialValue = false)
+ val touchesAllowed by viewModel.touchesAllowed.collectAsStateWithLifecycle()
val showGestureIndicator by
viewModel.showGestureIndicator.collectAsStateWithLifecycle(initialValue = false)
val backgroundType by
viewModel.communalBackground.collectAsStateWithLifecycle(
- initialValue = CommunalBackgroundType.DEFAULT
+ initialValue = CommunalBackgroundType.ANIMATED
)
val state: MutableSceneTransitionLayoutState = remember {
MutableSceneTransitionLayoutState(
@@ -243,7 +243,7 @@
) {
Box(modifier = Modifier.element(Communal.Elements.Scrim).fillMaxSize()) {
when (backgroundType) {
- CommunalBackgroundType.DEFAULT -> DefaultBackground(colors = colors)
+ CommunalBackgroundType.STATIC -> DefaultBackground(colors = colors)
CommunalBackgroundType.STATIC_GRADIENT -> StaticLinearGradient()
CommunalBackgroundType.ANIMATED -> AnimatedLinearGradient()
CommunalBackgroundType.NONE -> BackgroundTopScrim()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index e7f0af0..be51c1a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -484,6 +484,7 @@
rememberDragAndDropTargetState(
gridState = gridState,
contentListState = contentListState,
+ contentOffset = contentOffset,
updateDragPositionForRemove = updateDragPositionForRemove
)
@@ -546,7 +547,7 @@
}
} else {
CommunalContent(
- modifier = cardModifier.animateItemPlacement(),
+ modifier = cardModifier.animateItem(),
model = list[index],
viewModel = viewModel,
size = size,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
index 37fe798..9e6f22a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
@@ -41,7 +41,7 @@
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import com.android.systemui.communal.domain.model.CommunalContentModel
-import com.android.systemui.communal.ui.compose.extensions.plus
+import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset
import com.android.systemui.communal.util.WidgetPickerIntentUtils
import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent
import kotlinx.coroutines.CoroutineScope
@@ -57,6 +57,7 @@
@Composable
internal fun rememberDragAndDropTargetState(
gridState: LazyGridState,
+ contentOffset: Offset,
contentListState: ContentListState,
updateDragPositionForRemove: (offset: Offset) -> Boolean,
): DragAndDropTargetState {
@@ -70,6 +71,7 @@
remember(gridState, contentListState) {
DragAndDropTargetState(
state = gridState,
+ contentOffset = contentOffset,
contentListState = contentListState,
scope = scope,
autoScrollSpeed = autoScrollSpeed,
@@ -145,6 +147,7 @@
*/
internal class DragAndDropTargetState(
private val state: LazyGridState,
+ private val contentOffset: Offset,
private val contentListState: ContentListState,
private val scope: CoroutineScope,
private val autoScrollSpeed: MutableState<Float>,
@@ -214,8 +217,7 @@
return@let true
}
return false
- }
- ?: false
+ } ?: false
}
fun onEnded() {
@@ -249,10 +251,9 @@
}
private fun findTargetItem(dragEvent: DragEvent): LazyGridItemInfo? =
- state.layoutInfo.visibleItemsInfo.firstOrNull { item ->
- dragEvent.x.toInt() in item.offset.x..(item.offset + item.size).x &&
- dragEvent.y.toInt() in item.offset.y..(item.offset + item.size).y
- }
+ state.layoutInfo.visibleItemsInfo.firstItemAtOffset(
+ Offset(dragEvent.x, dragEvent.y) - contentOffset
+ )
private fun movePlaceholderTo(index: Int) {
val currentIndex = contentListState.list.indexOf(placeHolder)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
index 1051095..07898b0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
@@ -108,7 +108,12 @@
private val draggingItemLayoutInfo: LazyGridItemInfo?
get() = state.layoutInfo.visibleItemsInfo.firstOrNull { it.index == draggingItemIndex }
- internal fun onDragStart(offset: Offset, contentOffset: Offset) {
+ /**
+ * Called when dragging is initiated.
+ *
+ * @return {@code True} if dragging a grid item, {@code False} otherwise.
+ */
+ internal fun onDragStart(offset: Offset, contentOffset: Offset): Boolean {
state.layoutInfo.visibleItemsInfo
.filter { item -> contentListState.isItemEditable(item.index) }
// grid item offset is based off grid content container so we need to deduct
@@ -118,7 +123,10 @@
dragStartPointerOffset = offset - this.offset.toOffset()
draggingItemIndex = index
draggingItemInitialOffset = this.offset.toOffset()
+ return true
}
+
+ return false
}
internal fun onDragInterrupted() {
@@ -216,8 +224,9 @@
dragDropState.onDrag(offset = offset)
},
onDragStart = { offset ->
- dragDropState.onDragStart(offset, contentOffset)
- viewModel.onReorderWidgetStart()
+ if (dragDropState.onDragStart(offset, contentOffset)) {
+ viewModel.onReorderWidgetStart()
+ }
},
onDragEnd = {
dragDropState.onDragInterrupted()
@@ -261,7 +270,7 @@
alpha = itemAlpha
}
} else {
- Modifier.animateItemPlacement()
+ Modifier.animateItem()
}
// Animate the highlight alpha manually as alpha modifier (and AnimatedVisibility) clips the
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
index 418df5c..0b96694 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
@@ -89,7 +89,7 @@
// Content.
val contentColor = LocalAndroidColorScheme.current.onSurfaceVariant
- Box(Modifier.defaultMinSize(minHeight = 48.dp)) {
+ Box {
CompositionLocalProvider(LocalContentColor provides contentColor) {
ProvideTextStyle(
MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.Center)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
index 4555f13..c34fb38 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
@@ -19,9 +19,10 @@
package com.android.systemui.keyguard.ui.composable
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.indication
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
@@ -33,12 +34,14 @@
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.input.pointer.pointerInput
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
+import com.android.systemui.communal.ui.compose.extensions.detectLongPressGesture
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
/** Container for lockscreen content that handles long-press to bring up the settings menu. */
@Composable
+// TODO(b/344879669): now that it's more generic than long-press, rename it.
fun LockscreenLongPress(
- viewModel: KeyguardLongPressViewModel,
+ viewModel: KeyguardTouchHandlingViewModel,
modifier: Modifier = Modifier,
content: @Composable BoxScope.(onSettingsMenuPlaces: (coordinates: Rect?) -> Unit) -> Unit,
) {
@@ -50,14 +53,17 @@
Box(
modifier =
modifier
- .combinedClickable(
- enabled = isEnabled,
- onLongClick = viewModel::onLongPress,
- onClick = {},
- interactionSource = interactionSource,
- // Passing null for the indication removes the ripple effect.
- indication = null,
- )
+ .pointerInput(isEnabled) {
+ if (isEnabled) {
+ detectLongPressGesture { viewModel.onLongPress() }
+ }
+ }
+ .pointerInput(Unit) {
+ detectTapGestures(
+ onTap = { viewModel.onClick(it.x, it.y) },
+ onDoubleTap = { viewModel.onDoubleClick() },
+ )
+ }
.pointerInput(settingsMenuBounds) {
awaitEachGesture {
val pointerInputChange = awaitFirstDown()
@@ -65,7 +71,9 @@
viewModel.onTouchedOutside()
}
}
- },
+ }
+ // Passing null for the indication removes the ripple effect.
+ .indication(interactionSource, null)
) {
content(setSettingsMenuBounds)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt
index 6b210af..210ca69 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt
@@ -43,7 +43,7 @@
@Composable
override fun SceneScope.Content(modifier: Modifier) {
LockscreenLongPress(
- viewModel = viewModel.longPress,
+ viewModel = viewModel.touchHandling,
modifier = modifier,
) { _ ->
Box(modifier.background(Color.Black)) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index a39fa64..0a4c6fd 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -72,7 +72,7 @@
val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
LockscreenLongPress(
- viewModel = viewModel.longPress,
+ viewModel = viewModel.touchHandling,
modifier = modifier,
) { onSettingsMenuPlaced ->
Layout(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
index c83f62c..065f2a2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
@@ -74,7 +74,7 @@
val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
LockscreenLongPress(
- viewModel = viewModel.longPress,
+ viewModel = viewModel.touchHandling,
modifier = modifier,
) { onSettingsMenuPlaced ->
Layout(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt
index 44b0535..15032e0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt
@@ -30,8 +30,8 @@
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible
import com.android.systemui.keyguard.ui.binder.KeyguardSettingsViewBinder
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
@@ -42,7 +42,7 @@
@Inject
constructor(
private val viewModel: KeyguardSettingsMenuViewModel,
- private val longPressViewModel: KeyguardLongPressViewModel,
+ private val touchHandlingViewModel: KeyguardTouchHandlingViewModel,
private val vibratorHelper: VibratorHelper,
private val activityStarter: ActivityStarter,
) {
@@ -69,7 +69,7 @@
KeyguardSettingsViewBinder.bind(
view = this,
viewModel = viewModel,
- longPressViewModel = longPressViewModel,
+ touchHandlingViewModel = touchHandlingViewModel,
rootViewModel = null,
vibratorHelper = vibratorHelper,
activityStarter = activityStarter,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index 6805888..a568824 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -19,12 +19,19 @@
import android.util.Log
import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.tween
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollBy
+import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.absoluteOffset
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -40,9 +47,11 @@
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -51,6 +60,7 @@
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.boundsInWindow
@@ -58,10 +68,12 @@
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.layout.positionInWindow
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -70,6 +82,7 @@
import com.android.compose.animation.scene.NestedScrollBehavior
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.thenIf
+import com.android.internal.policy.SystemBarUtils
import com.android.systemui.common.ui.compose.windowinsets.LocalRawScreenHeight
import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
import com.android.systemui.res.R
@@ -136,6 +149,87 @@
)
}
+/**
+ * A version of [HeadsUpNotificationSpace] that can be swiped up off the top edge of the screen by
+ * the user. When swiped up, the heads up notification is snoozed.
+ */
+@Composable
+fun SceneScope.SnoozeableHeadsUpNotificationSpace(
+ stackScrollView: NotificationScrollView,
+ viewModel: NotificationsPlaceholderViewModel,
+) {
+ val context = LocalContext.current
+ val density = LocalDensity.current
+ val statusBarHeight = SystemBarUtils.getStatusBarHeight(context)
+ val headsUpPadding =
+ with(density) { dimensionResource(id = R.dimen.heads_up_status_bar_padding).roundToPx() }
+
+ val isHeadsUp by viewModel.isHeadsUpOrAnimatingAway.collectAsStateWithLifecycle(false)
+
+ var scrollOffset by remember { mutableFloatStateOf(0f) }
+ val minScrollOffset = -(statusBarHeight + headsUpPadding.toFloat())
+ val maxScrollOffset = 0f
+
+ val scrollableState = rememberScrollableState { delta ->
+ consumeDeltaWithinRange(
+ current = scrollOffset,
+ setCurrent = { scrollOffset = it },
+ min = minScrollOffset,
+ max = maxScrollOffset,
+ delta
+ )
+ }
+
+ val nestedScrollConnection =
+ object : NestedScrollConnection {
+ override suspend fun onPreFling(available: Velocity): Velocity {
+ if (
+ velocityOrPositionalThresholdReached(scrollOffset, minScrollOffset, available.y)
+ ) {
+ scrollableState.animateScrollBy(minScrollOffset, tween())
+ } else {
+ scrollableState.animateScrollBy(-minScrollOffset, tween())
+ }
+ return available
+ }
+ }
+
+ LaunchedEffect(isHeadsUp) { scrollOffset = 0f }
+
+ LaunchedEffect(scrollableState.isScrollInProgress) {
+ if (!scrollableState.isScrollInProgress && scrollOffset <= minScrollOffset) {
+ viewModel.snoozeHun()
+ }
+ }
+
+ HeadsUpNotificationSpace(
+ stackScrollView = stackScrollView,
+ viewModel = viewModel,
+ modifier =
+ Modifier.absoluteOffset {
+ IntOffset(
+ x = 0,
+ y =
+ calculateHeadsUpPlaceholderYOffset(
+ scrollOffset.roundToInt(),
+ minScrollOffset.roundToInt(),
+ stackScrollView.topHeadsUpHeight
+ )
+ )
+ }
+ .thenIf(isHeadsUp) {
+ Modifier.verticalNestedScrollToScene(
+ bottomBehavior = NestedScrollBehavior.EdgeAlways
+ )
+ .nestedScroll(nestedScrollConnection)
+ .scrollable(
+ orientation = Orientation.Vertical,
+ state = scrollableState,
+ )
+ }
+ )
+}
+
/** Adds the space where notification stack should appear in the scene. */
@Composable
fun SceneScope.ConstrainedNotificationStack(
@@ -233,6 +327,8 @@
// The height of the scrim visible on screen when it is in its resting (collapsed) state.
val minVisibleScrimHeight: () -> Float = { screenHeight - maxScrimTop() }
+ val isClickable by viewModel.isClickable.collectAsStateWithLifecycle()
+
// we are not scrolled to the top unless the scrim is at its maximum offset.
LaunchedEffect(viewModel, scrimOffset) {
snapshotFlow { scrimOffset.value >= 0f }
@@ -328,6 +424,9 @@
)
)
}
+ .thenIf(isClickable) {
+ Modifier.clickable(onClick = { viewModel.onEmptySpaceClicked() })
+ }
) {
// Creates a cutout in the background scrim in the shape of the notifications scrim.
// Only visible when notif scrim alpha < 1, during shade expansion.
@@ -474,6 +573,47 @@
}
}
+private fun calculateHeadsUpPlaceholderYOffset(
+ scrollOffset: Int,
+ minScrollOffset: Int,
+ topHeadsUpHeight: Int,
+): Int {
+ return -minScrollOffset +
+ (scrollOffset * (-minScrollOffset + topHeadsUpHeight) / -minScrollOffset)
+}
+
+private fun velocityOrPositionalThresholdReached(
+ scrollOffset: Float,
+ minScrollOffset: Float,
+ availableVelocityY: Float,
+): Boolean {
+ return availableVelocityY < HUN_SNOOZE_VELOCITY_THRESHOLD ||
+ (availableVelocityY <= 0f &&
+ scrollOffset < minScrollOffset * HUN_SNOOZE_POSITIONAL_THRESHOLD_FRACTION)
+}
+
+/**
+ * Takes a range, current value, and delta, and updates the current value by the delta, coercing the
+ * result within the given range. Returns how much of the delta was consumed.
+ */
+private fun consumeDeltaWithinRange(
+ current: Float,
+ setCurrent: (Float) -> Unit,
+ min: Float,
+ max: Float,
+ delta: Float
+): Float {
+ return if (delta < 0 && current > min) {
+ val remainder = (current + delta - min).coerceAtMost(0f)
+ setCurrent((current + delta).coerceAtLeast(min))
+ delta - remainder
+ } else if (delta > 0 && current < max) {
+ val remainder = (current + delta).coerceAtLeast(0f)
+ setCurrent((current + delta).coerceAtMost(max))
+ delta - remainder
+ } else 0f
+}
+
private inline fun debugLog(
viewModel: NotificationsPlaceholderViewModel,
msg: () -> Any,
@@ -508,3 +648,5 @@
private val DEBUG_STACK_COLOR = Color(1f, 0f, 0f, 0.2f)
private val DEBUG_HUN_COLOR = Color(0f, 0f, 1f, 0.2f)
private val DEBUG_BOX_COLOR = Color(0f, 1f, 0f, 0.2f)
+private const val HUN_SNOOZE_POSITIONAL_THRESHOLD_FRACTION = 0.25f
+private const val HUN_SNOOZE_VELOCITY_THRESHOLD = -70f
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt
index 73a624a..aca473d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt
@@ -18,8 +18,9 @@
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
@@ -39,6 +40,7 @@
viewModel: BrightnessMirrorViewModel,
qsSceneAdapter: QSSceneAdapter,
modifier: Modifier = Modifier,
+ measureFromContainer: Boolean = false,
) {
val isShowing by viewModel.isShowing.collectAsStateWithLifecycle()
val mirrorAlpha by
@@ -47,9 +49,22 @@
label = "alphaAnimationBrightnessMirrorShowing",
)
val mirrorOffsetAndSize by viewModel.locationAndSize.collectAsStateWithLifecycle()
- val offset = IntOffset(0, mirrorOffsetAndSize.yOffset)
+ val yOffset =
+ if (measureFromContainer) {
+ mirrorOffsetAndSize.yOffsetFromContainer
+ } else {
+ mirrorOffsetAndSize.yOffsetFromWindow
+ }
+ val offset = IntOffset(0, yOffset)
- Box(modifier = modifier.fillMaxSize().graphicsLayer { alpha = mirrorAlpha }) {
+ // Use unbounded=true as the full mirror (with paddings and background offset) may be larger
+ // than the space we have (but it will fit, because the brightness slider fits).
+ Box(
+ modifier =
+ modifier.fillMaxHeight().wrapContentWidth(unbounded = true).graphicsLayer {
+ alpha = mirrorAlpha
+ }
+ ) {
QuickSettingsTheme {
// The assumption for using this AndroidView is that there will be only one in view at
// a given time (which is a reasonable assumption). Because `QSSceneAdapter` (actually
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 0b57151..2d5d259 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -185,7 +185,11 @@
BrightnessMirror(
viewModel = viewModel.brightnessMirrorViewModel,
- qsSceneAdapter = viewModel.qsSceneAdapter
+ qsSceneAdapter = viewModel.qsSceneAdapter,
+ modifier =
+ Modifier.thenIf(cutoutLocation != CutoutLocation.CENTER) {
+ Modifier.displayCutoutPadding()
+ }
)
val shouldPunchHoleBehindScrim =
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
index c066ae5..422c9f6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
@@ -16,14 +16,14 @@
package com.android.systemui.qs.ui.composable
-import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
+import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@@ -46,6 +46,9 @@
import com.android.systemui.keyguard.ui.composable.LockscreenContent
import com.android.systemui.qs.panels.ui.compose.EditMode
import com.android.systemui.qs.panels.ui.compose.TileGrid
+import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutEnter
+import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutExit
+import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneViewModel
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.ComposableScene
@@ -95,7 +98,7 @@
)
ShadeBody(
- viewModel = viewModel,
+ viewModel = viewModel.quickSettingsContainerViewModel,
)
}
}
@@ -104,39 +107,30 @@
@Composable
private fun ShadeBody(
- viewModel: QuickSettingsShadeSceneViewModel,
+ viewModel: QuickSettingsContainerViewModel,
) {
val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle()
- Box {
- // The main Quick Settings grid layout.
- AnimatedVisibility(
- visible = !isEditing,
- enter = QuickSettingsShade.Transitions.QuickSettingsLayoutEnter,
- exit = QuickSettingsShade.Transitions.QuickSettingsLayoutExit,
- ) {
- QuickSettingsLayout(
- viewModel = viewModel,
- )
- }
-
- // The Quick Settings Editor layout.
- AnimatedVisibility(
- visible = isEditing,
- enter = QuickSettingsShade.Transitions.QuickSettingsEditorEnter,
- exit = QuickSettingsShade.Transitions.QuickSettingsEditorExit,
- ) {
+ AnimatedContent(
+ targetState = isEditing,
+ transitionSpec = { QuickSettingsLayoutEnter togetherWith QuickSettingsLayoutExit }
+ ) { editing ->
+ if (editing) {
EditMode(
viewModel = viewModel.editModeViewModel,
modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding)
)
+ } else {
+ QuickSettingsLayout(
+ viewModel = viewModel,
+ )
}
}
}
@Composable
private fun QuickSettingsLayout(
- viewModel: QuickSettingsShadeSceneViewModel,
+ viewModel: QuickSettingsContainerViewModel,
modifier: Modifier = Modifier,
) {
Column(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt
index 924aa54..4eaacf3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt
@@ -86,7 +86,7 @@
*/
@Composable
fun <T> Session.rememberSession(vararg inputs: Any?, key: String? = null, init: () -> T): T =
- rememberSession(key, inputs, init = init)
+ rememberSession(key, *inputs, init = init)
/**
* An explicit storage for remembering composable state outside of the lifetime of a composition.
@@ -151,7 +151,7 @@
vararg inputs: Any?,
key: String? = null,
): SaveableSession =
- rememberSaveable(inputs, SaveableSessionImpl.SessionSaver, key) { SaveableSessionImpl() }
+ rememberSaveable(*inputs, SaveableSessionImpl.SessionSaver, key) { SaveableSessionImpl() }
private class SessionImpl(
private val storage: SessionStorage = SessionStorage(),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 4e334c2..a44041a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -17,26 +17,19 @@
package com.android.systemui.scene.ui.composable
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.absoluteOffset
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.unit.IntOffset
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.animateSceneDpAsState
import com.android.compose.animation.scene.animateSceneFloatAsState
-import com.android.internal.policy.SystemBarUtils
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace
+import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace
import com.android.systemui.qs.ui.composable.QuickSettings
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.Default
-import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.GoneSceneViewModel
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
@@ -72,28 +65,9 @@
)
animateSceneDpAsState(value = Default, key = MediaLandscapeTopOffset, canOverflow = false)
Spacer(modifier.fillMaxSize())
- HeadsUpNotificationStack(
+ SnoozeableHeadsUpNotificationSpace(
stackScrollView = notificationStackScrolLView.get(),
viewModel = notificationsPlaceholderViewModel
)
}
}
-
-@Composable
-private fun SceneScope.HeadsUpNotificationStack(
- stackScrollView: NotificationScrollView,
- viewModel: NotificationsPlaceholderViewModel,
-) {
- val context = LocalContext.current
- val density = LocalDensity.current
- val statusBarHeight = SystemBarUtils.getStatusBarHeight(context)
- val headsUpPadding =
- with(density) { dimensionResource(id = R.dimen.heads_up_status_bar_padding).roundToPx() }
-
- HeadsUpNotificationSpace(
- stackScrollView = stackScrollView,
- viewModel = viewModel,
- modifier =
- Modifier.absoluteOffset { IntOffset(x = 0, y = statusBarHeight + headsUpPadding) }
- )
-}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 22566e7..9c9e6c6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -34,6 +34,8 @@
import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayout
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.observableTransitionState
import com.android.systemui.ribbon.ui.composable.BottomRightCornerRibbon
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -56,7 +58,6 @@
* must have entries in this map.
* @param modifier A modifier.
*/
-@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun SceneContainer(
viewModel: SceneContainerViewModel,
@@ -66,8 +67,6 @@
) {
val coroutineScope = rememberCoroutineScope()
val currentSceneKey: SceneKey by viewModel.currentScene.collectAsStateWithLifecycle()
- val currentDestinations by
- viewModel.currentDestinationScenes(coroutineScope).collectAsStateWithLifecycle()
val state: MutableSceneTransitionLayoutState = remember {
MutableSceneTransitionLayoutState(
initialScene = currentSceneKey,
@@ -88,20 +87,19 @@
onDispose { viewModel.setTransitionState(null) }
}
+ val userActionsBySceneKey: Map<SceneKey, Map<UserAction, UserActionResult>> =
+ sceneByKey.values.associate { scene ->
+ val userActions by scene.destinationScenes.collectAsStateWithLifecycle(emptyMap())
+ val resolvedUserActions = viewModel.resolveSceneFamilies(userActions)
+ scene.key to resolvedUserActions
+ }
+
Box(
modifier = Modifier.fillMaxSize(),
) {
SceneTransitionLayout(state = state, modifier = modifier.fillMaxSize()) {
sceneByKey.forEach { (sceneKey, composableScene) ->
- scene(
- key = sceneKey,
- userActions =
- if (sceneKey == currentSceneKey) {
- currentDestinations
- } else {
- viewModel.resolveSceneFamilies(composableScene.destinationScenes.value)
- },
- ) {
+ scene(key = sceneKey, userActions = checkNotNull(userActionsBySceneKey[sceneKey])) {
with(composableScene) {
this@scene.Content(
modifier = Modifier.element(sceneKey.rootElementKey).fillMaxSize(),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index edef5fb..4a6599a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -36,7 +36,6 @@
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.navigationBarsPadding
-import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -97,6 +96,7 @@
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
+import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
import com.android.systemui.statusbar.phone.ui.TintedIconManager
@@ -138,6 +138,7 @@
private val shadeSession: SaveableSession,
private val notificationStackScrollView: Lazy<NotificationScrollView>,
private val viewModel: ShadeSceneViewModel,
+ private val notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
private val tintedIconManagerFactory: TintedIconManager.Factory,
private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
private val statusBarIconController: StatusBarIconController,
@@ -157,6 +158,7 @@
ShadeScene(
notificationStackScrollView.get(),
viewModel = viewModel,
+ notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
createTintedIconManager = tintedIconManagerFactory::create,
createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
statusBarIconController = statusBarIconController,
@@ -177,6 +179,7 @@
private fun SceneScope.ShadeScene(
notificationStackScrollView: NotificationScrollView,
viewModel: ShadeSceneViewModel,
+ notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
statusBarIconController: StatusBarIconController,
@@ -191,6 +194,7 @@
SingleShade(
notificationStackScrollView = notificationStackScrollView,
viewModel = viewModel,
+ notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
createTintedIconManager = createTintedIconManager,
createBatteryMeterViewController = createBatteryMeterViewController,
statusBarIconController = statusBarIconController,
@@ -203,6 +207,7 @@
SplitShade(
notificationStackScrollView = notificationStackScrollView,
viewModel = viewModel,
+ notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
createTintedIconManager = createTintedIconManager,
createBatteryMeterViewController = createBatteryMeterViewController,
statusBarIconController = statusBarIconController,
@@ -219,6 +224,7 @@
private fun SceneScope.SingleShade(
notificationStackScrollView: NotificationScrollView,
viewModel: ShadeSceneViewModel,
+ notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
statusBarIconController: StatusBarIconController,
@@ -330,7 +336,7 @@
NotificationScrollingStack(
shadeSession = shadeSession,
stackScrollView = notificationStackScrollView,
- viewModel = viewModel.notifications,
+ viewModel = notificationsPlaceholderViewModel,
maxScrimTop = { maxNotifScrimTop.value },
shadeMode = ShadeMode.Single,
shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim,
@@ -354,7 +360,7 @@
}
NotificationStackCutoffGuideline(
stackScrollView = notificationStackScrollView,
- viewModel = viewModel.notifications,
+ viewModel = notificationsPlaceholderViewModel,
modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding()
)
}
@@ -364,6 +370,7 @@
private fun SceneScope.SplitShade(
notificationStackScrollView: NotificationScrollView,
viewModel: ShadeSceneViewModel,
+ notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
statusBarIconController: StatusBarIconController,
@@ -431,8 +438,10 @@
label = "alphaAnimationBrightnessMirrorContentHiding",
)
- viewModel.notifications.setAlphaForBrightnessMirror(contentAlpha)
- DisposableEffect(Unit) { onDispose { viewModel.notifications.setAlphaForBrightnessMirror(1f) } }
+ notificationsPlaceholderViewModel.setAlphaForBrightnessMirror(contentAlpha)
+ DisposableEffect(Unit) {
+ onDispose { notificationsPlaceholderViewModel.setAlphaForBrightnessMirror(1f) }
+ }
val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle()
@@ -474,9 +483,9 @@
BrightnessMirror(
viewModel = viewModel.brightnessMirrorViewModel,
qsSceneAdapter = viewModel.qsSceneAdapter,
- // Need to remove the offset of the header height, as the mirror uses
- // the position of the Brightness slider in the window
- modifier = Modifier.offset(y = -ShadeHeader.Dimensions.CollapsedHeight)
+ // Need to use the offset measured from the container as the header
+ // has to be accounted for
+ measureFromContainer = true
)
Column(
verticalArrangement = Arrangement.Top,
@@ -533,7 +542,7 @@
NotificationScrollingStack(
shadeSession = shadeSession,
stackScrollView = notificationStackScrollView,
- viewModel = viewModel.notifications,
+ viewModel = notificationsPlaceholderViewModel,
maxScrimTop = { 0f },
shouldPunchHoleBehindScrim = false,
shouldReserveSpaceForNavBar = false,
@@ -548,7 +557,7 @@
}
NotificationStackCutoffGuideline(
stackScrollView = notificationStackScrollView,
- viewModel = viewModel.notifications,
+ viewModel = notificationsPlaceholderViewModel,
modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding()
)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index fbf91b7..a23bb67 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -48,6 +48,7 @@
import com.android.compose.PlatformSliderColors
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderState
@Composable
@@ -62,7 +63,7 @@
val value by valueState(state)
PlatformSlider(
modifier =
- modifier.clearAndSetSemantics {
+ modifier.sysuiResTag(state.label).clearAndSetSemantics {
if (state.isEnabled) {
contentDescription = state.label
state.a11yClickDescription?.let {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
index ab14911..9da2a1b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
@@ -25,20 +25,25 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.paneTitle
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.res.R
import com.android.systemui.volume.panel.ui.layout.ComponentsLayout
import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState
import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
+/** Same as android.platform.systemui_tapl.ui.VolumePanel#VolumePanelTestTag */
+private const val VolumePanelTestTag = "VolumePanel"
private val padding = 24.dp
@Composable
+@OptIn(ExperimentalComposeUiApi::class)
fun VolumePanelRoot(
viewModel: VolumePanelViewModel,
modifier: Modifier = Modifier,
@@ -52,6 +57,7 @@
Components(
componentsState,
modifier
+ .sysuiResTag(VolumePanelTestTag)
.semantics { paneTitle = accessibilityTitle }
.padding(
start = padding,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
new file mode 100644
index 0000000..dfb8c49
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2024 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.compose.animation.scene
+
+import androidx.activity.BackEventCompat
+import androidx.activity.compose.PredictiveBackHandler
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import kotlin.coroutines.cancellation.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+
+@Composable
+internal fun PredictiveBackHandler(
+ state: BaseSceneTransitionLayoutState,
+ coroutineScope: CoroutineScope,
+ targetSceneForBack: SceneKey? = null,
+) {
+ PredictiveBackHandler(
+ enabled = targetSceneForBack != null,
+ ) { progress: Flow<BackEventCompat> ->
+ val fromScene = state.transitionState.currentScene
+ if (targetSceneForBack == null || targetSceneForBack == fromScene) {
+ // Note: We have to collect progress otherwise PredictiveBackHandler will throw.
+ progress.first()
+ return@PredictiveBackHandler
+ }
+
+ val transition =
+ PredictiveBackTransition(state, coroutineScope, fromScene, toScene = targetSceneForBack)
+ state.startTransition(transition)
+ try {
+ progress.collect { backEvent -> transition.dragProgress = backEvent.progress }
+
+ // Back gesture successful.
+ transition.animateTo(
+ if (state.canChangeScene(targetSceneForBack)) {
+ targetSceneForBack
+ } else {
+ fromScene
+ }
+ )
+ } catch (e: CancellationException) {
+ // Back gesture cancelled.
+ transition.animateTo(fromScene)
+ }
+ }
+}
+
+private class PredictiveBackTransition(
+ val state: BaseSceneTransitionLayoutState,
+ val coroutineScope: CoroutineScope,
+ fromScene: SceneKey,
+ toScene: SceneKey,
+) : TransitionState.Transition(fromScene, toScene) {
+ override var currentScene by mutableStateOf(fromScene)
+ private set
+
+ /** The animated progress once the gesture was committed or cancelled. */
+ private var progressAnimatable by mutableStateOf<Animatable<Float, AnimationVector1D>?>(null)
+ var dragProgress: Float by mutableFloatStateOf(0f)
+
+ override val progress: Float
+ get() = progressAnimatable?.value ?: dragProgress
+
+ override val progressVelocity: Float
+ get() = progressAnimatable?.velocity ?: 0f
+
+ override val isInitiatedByUserInput: Boolean
+ get() = true
+
+ override val isUserInputOngoing: Boolean
+ get() = progressAnimatable == null
+
+ private var animationJob: Job? = null
+
+ override fun finish(): Job = animateTo(currentScene)
+
+ fun animateTo(scene: SceneKey): Job {
+ check(scene == fromScene || scene == toScene)
+ animationJob?.let {
+ return it
+ }
+
+ currentScene = scene
+ val targetProgress =
+ when (scene) {
+ fromScene -> 0f
+ toScene -> 1f
+ else -> error("scene $scene should be either $fromScene or $toScene")
+ }
+
+ val animatable = Animatable(dragProgress).also { progressAnimatable = it }
+
+ // Important: We start atomically to make sure that we start the coroutine even if it is
+ // cancelled right after it is launched, so that finishTransition() is correctly called.
+ return coroutineScope
+ .launch(start = CoroutineStart.ATOMIC) {
+ try {
+ animatable.animateTo(targetProgress)
+ } finally {
+ state.finishTransition(this@PredictiveBackTransition, scene)
+ }
+ }
+ .also { animationJob = it }
+ }
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index 7ea8cbd..6095419 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -16,7 +16,6 @@
package com.android.compose.animation.scene
-import androidx.activity.compose.BackHandler
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
@@ -213,16 +212,9 @@
@Composable
private fun BackHandler() {
- val targetSceneForBackOrNull =
+ val targetSceneForBack =
scene(state.transitionState.currentScene).userActions[Back]?.toScene
- BackHandler(enabled = targetSceneForBackOrNull != null) {
- targetSceneForBackOrNull?.let { targetSceneForBack ->
- // TODO(b/290184746): Handle predictive back and use result.distance if specified.
- if (state.canChangeScene(targetSceneForBack)) {
- with(state) { coroutineScope.onChangeScene(targetSceneForBack) }
- }
- }
- }
+ PredictiveBackHandler(state, coroutineScope, targetSceneForBack)
}
private fun scenesToCompose(): List<Scene> {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index a8dd572..1c8efb8 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -16,6 +16,7 @@
package com.android.compose.animation.scene
+import androidx.activity.BackEventCompat
import androidx.activity.ComponentActivity
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearEasing
@@ -168,12 +169,47 @@
assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
- rule.activity.onBackPressed()
+ rule.runOnUiThread { rule.activity.onBackPressedDispatcher.onBackPressed() }
rule.waitForIdle()
assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
}
@Test
+ fun testPredictiveBack() {
+ rule.setContent { TestContent() }
+
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+
+ // Start back.
+ val dispatcher = rule.activity.onBackPressedDispatcher
+ rule.runOnUiThread {
+ dispatcher.dispatchOnBackStarted(backEvent())
+ dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
+ }
+
+ val transition = assertThat(layoutState.transitionState).isTransition()
+ assertThat(transition).hasFromScene(SceneA)
+ assertThat(transition).hasToScene(SceneB)
+ assertThat(transition).hasProgress(0.4f)
+
+ // Cancel it.
+ rule.runOnUiThread { dispatcher.dispatchOnBackCancelled() }
+ rule.waitForIdle()
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+ assertThat(layoutState.transitionState).isIdle()
+
+ // Start again and commit it.
+ rule.runOnUiThread {
+ dispatcher.dispatchOnBackStarted(backEvent())
+ dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
+ dispatcher.onBackPressed()
+ }
+ rule.waitForIdle()
+ assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
+ assertThat(layoutState.transitionState).isIdle()
+ }
+
+ @Test
fun testTransitionState() {
rule.setContent { TestContent() }
assertThat(layoutState.transitionState).isIdle()
@@ -524,4 +560,13 @@
assertThat(keyInB).isEqualTo(SceneB)
assertThat(keyInC).isEqualTo(SceneC)
}
+
+ private fun backEvent(progress: Float = 0f): BackEventCompat {
+ return BackEventCompat(
+ touchX = 0f,
+ touchY = 0f,
+ progress = progress,
+ swipeEdge = BackEventCompat.EDGE_LEFT,
+ )
+ }
}
diff --git a/packages/SystemUI/lint-baseline.xml b/packages/SystemUI/lint-baseline.xml
index 2fd7f1b..525839d 100644
--- a/packages/SystemUI/lint-baseline.xml
+++ b/packages/SystemUI/lint-baseline.xml
@@ -128,7 +128,7 @@
errorLine1=" mUserTracker.addCallback(mUserChangedCallback, mContext.getMainExecutor());"
errorLine2=" ~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="807"
column="65"/>
</issue>
@@ -1646,7 +1646,7 @@
errorLine1=" mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);"
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="177"
column="48"/>
</issue>
@@ -2086,7 +2086,7 @@
errorLine1=" WindowManager wm = getContext().getSystemService(WindowManager.class);"
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="729"
column="45"/>
</issue>
@@ -2097,7 +2097,7 @@
errorLine1=" WindowManager wm = getContext().getSystemService(WindowManager.class);"
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="830"
column="41"/>
</issue>
@@ -4049,7 +4049,7 @@
errorLine1=" pw.println(String.format(" mCurrentView: id=%s (%dx%d) %s %f","
errorLine2=" ^">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="1128"
column="20"/>
</issue>
@@ -4060,7 +4060,7 @@
errorLine1=" pw.println(String.format(" disabled=0x%08x vertical=%s darkIntensity=%.2f","
errorLine2=" ^">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="1134"
column="20"/>
</issue>
@@ -4668,7 +4668,7 @@
errorLine1=" 500).show();"
errorLine2=" ~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="1894"
column="21"/>
</issue>
@@ -8386,7 +8386,7 @@
errorLine1=" mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="1500"
column="60"/>
</issue>
@@ -23055,7 +23055,7 @@
errorLine1=" mBarTransitions.setBackgroundFrame(new Rect(0, frameHeight - height, w, h));"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="1001"
column="48"/>
</issue>
@@ -25002,7 +25002,7 @@
errorLine1=" mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());"
errorLine2=" ~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="373"
column="70"/>
</issue>
@@ -25222,7 +25222,7 @@
errorLine1=" Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);"
errorLine2=" ~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java"
line="329"
column="74"/>
</issue>
@@ -25233,7 +25233,7 @@
errorLine1=" Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);"
errorLine2=" ~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java"
line="357"
column="74"/>
</issue>
@@ -25827,7 +25827,7 @@
errorLine1=" new AsyncTask<Icon, Void, Drawable>() {"
errorLine2=" ^">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="207"
column="9"/>
</issue>
@@ -29303,7 +29303,7 @@
errorLine1=" public boolean onTouchEvent(MotionEvent ev) {"
errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
line="267"
column="20"/>
</issue>
@@ -29578,7 +29578,7 @@
errorLine1=" mView.setOnTouchListener(this::onNavigationTouch);"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
line="782"
column="9"/>
</issue>
@@ -29589,7 +29589,7 @@
errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
line="383"
column="20"/>
</issue>
@@ -29600,7 +29600,7 @@
errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java"
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java"
line="207"
column="20"/>
</issue>
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
index 630bcd6..7ebc224 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
@@ -21,6 +21,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
@@ -49,6 +50,7 @@
import com.android.systemui.ambient.touch.scrim.ScrimController;
import com.android.systemui.ambient.touch.scrim.ScrimManager;
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
+import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.FakeUserTracker;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shared.system.InputChannelCompat;
@@ -113,6 +115,9 @@
LockPatternUtils mLockPatternUtils;
@Mock
+ ActivityStarter mActivityStarter;
+
+ @Mock
Region mRegion;
@Captor
@@ -148,7 +153,8 @@
mFlingAnimationUtilsClosing,
TOUCH_REGION,
MIN_BOUNCER_HEIGHT,
- mUiEventLogger);
+ mUiEventLogger,
+ mActivityStarter);
when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
@@ -397,7 +403,12 @@
.isTrue();
// We should not expand since the keyguard is not secure
verify(mScrimController, never()).expand(any());
- // Since we are swiping up, we should wake from dreams.
+
+ // Since we are swiping up, we should dismiss the keyguard and wake from dreams.
+ ArgumentCaptor<Runnable> dismissKeyguardRunnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mActivityStarter).executeRunnableDismissingKeyguard(
+ dismissKeyguardRunnable.capture(), isNull(), eq(true), eq(true), eq(false));
+ dismissKeyguardRunnable.getValue().run();
verify(mCentralSurfaces).awakenDreams();
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 60b48f2..242e822 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -324,7 +324,6 @@
fun showUdfpsOverlay_awake() =
testScope.runTest {
withReason(REASON_AUTH_KEYGUARD) {
- mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
powerRepository.updateWakefulness(
rawState = WakefulnessState.AWAKE,
lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -341,7 +340,6 @@
fun showUdfpsOverlay_whileGoingToSleep() =
testScope.runTest {
withReasonSuspend(REASON_AUTH_KEYGUARD) {
- mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.OFF,
to = KeyguardState.GONE,
@@ -370,7 +368,6 @@
fun showUdfpsOverlay_whileAsleep() =
testScope.runTest {
withReasonSuspend(REASON_AUTH_KEYGUARD) {
- mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.OFF,
to = KeyguardState.GONE,
@@ -399,7 +396,6 @@
fun neverRemoveViewThatHasNotBeenAdded() =
testScope.runTest {
withReasonSuspend(REASON_AUTH_KEYGUARD) {
- mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
controllerOverlay.show(udfpsController, overlayParams)
val view = controllerOverlay.getTouchOverlay()
view?.let {
@@ -414,7 +410,6 @@
fun showUdfpsOverlay_afterFinishedTransitioningToAOD() =
testScope.runTest {
withReasonSuspend(REASON_AUTH_KEYGUARD) {
- mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.OFF,
to = KeyguardState.GONE,
@@ -542,7 +537,6 @@
fun addViewPending_layoutIsNotUpdated() =
testScope.runTest {
withReasonSuspend(REASON_AUTH_KEYGUARD) {
- mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
// GIVEN going to sleep
@@ -580,7 +574,6 @@
fun updateOverlayParams_viewLayoutUpdated() =
testScope.runTest {
withReasonSuspend(REASON_AUTH_KEYGUARD) {
- mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
powerRepository.updateWakefulness(
rawState = WakefulnessState.AWAKE,
lastWakeReason = WakeSleepReason.POWER_BUTTON,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index fa79ea0..54e0725 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -1284,6 +1284,41 @@
}
@Test
+ public void onAodDownAndDownTouchReceived() throws RemoteException {
+ final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
+ 0L);
+ final TouchProcessorResult processorResultDown =
+ new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN,
+ -1 /* pointerId */, touchData);
+
+ mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+ BiometricRequestConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+
+ // WHEN fingerprint is requested because of AOD interrupt
+ // GIVEN there's been an AoD interrupt
+ when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
+ mScreenObserver.onScreenTurnedOn();
+ mUdfpsController.onAodInterrupt(0, 0, 0, 0);
+ mFgExecutor.runAllReady();
+
+ // and an ACTION_DOWN is received and touch is within sensor
+ when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
+ processorResultDown);
+ MotionEvent firstDownEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, firstDownEvent);
+ mBiometricExecutor.runAllReady();
+ firstDownEvent.recycle();
+
+ // THEN the touch is only processed once
+ verify(mFingerprintManager).onPointerDown(anyLong(), anyInt(), anyInt(),
+ anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(),
+ anyBoolean());
+ }
+
+ @Test
public void onTouch_pilferPointerWhenAltBouncerShowing()
throws RemoteException {
final Pair<TouchProcessorResult, TouchProcessorResult> touchProcessorResult =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
index fe683e07..dcc9c7a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
@@ -47,6 +47,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
+@EnableFlags(Flags.FLAG_COMMUNAL_HUB)
@RunWith(AndroidJUnit4::class)
class CommunalDreamStartableTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -76,7 +77,7 @@
testScope.runTest {
keyguardRepository.setDreaming(false)
powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
- whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+ whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
runCurrent()
verify(dreamManager, never()).startDream()
@@ -92,7 +93,7 @@
testScope.runTest {
keyguardRepository.setDreaming(false)
powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
- whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+ whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
runCurrent()
verify(dreamManager, never()).startDream()
@@ -118,7 +119,7 @@
keyguardRepository.setDreaming(false)
powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
// Not eligible to dream
- whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(false)
+ whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(false)
transition(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB)
verify(dreamManager, never()).startDream()
@@ -129,7 +130,7 @@
testScope.runTest {
keyguardRepository.setDreaming(true)
powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
- whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+ whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
transition(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB)
verify(dreamManager, never()).startDream()
@@ -140,7 +141,7 @@
testScope.runTest {
keyguardRepository.setDreaming(true)
powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
- whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+ whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
// Verify we do not trigger dreaming for any other state besides glanceable hub
for (state in KeyguardState.entries) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index fbe2c2e..cf14547 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -451,24 +451,6 @@
}
}
- @Test
- fun transitionFromDozingToGlanceableHub_forcesCommunal() =
- with(kosmos) {
- testScope.runTest {
- val scene by collectLastValue(communalSceneInteractor.currentScene)
- communalSceneInteractor.changeScene(CommunalScenes.Blank)
- assertThat(scene).isEqualTo(CommunalScenes.Blank)
-
- fakeKeyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.DOZING,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = this
- )
-
- assertThat(scene).isEqualTo(CommunalScenes.Communal)
- }
- }
-
private fun TestScope.updateDocked(docked: Boolean) =
with(kosmos) {
runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
index fb2b33d..0169f99 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
@@ -20,7 +20,6 @@
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
import android.app.admin.devicePolicyManager
-import android.appwidget.AppWidgetProviderInfo
import android.content.Intent
import android.content.pm.UserInfo
import android.os.UserManager.USER_TYPE_PROFILE_MANAGED
@@ -29,7 +28,6 @@
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.settingslib.flags.Flags.FLAG_ALLOW_ALL_WIDGETS_ON_LOCKSCREEN_BY_DEFAULT
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.broadcastDispatcher
@@ -183,47 +181,11 @@
)
}
- @EnableFlags(FLAG_COMMUNAL_HUB)
- @Test
- fun hubShowsWidgetCategoriesSetByUser() =
- testScope.runTest {
- kosmos.fakeSettings.putIntForUser(
- CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
- AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
- PRIMARY_USER.id
- )
- val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER))
- assertThat(setting?.categories)
- .isEqualTo(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN)
- }
-
- @EnableFlags(FLAG_COMMUNAL_HUB)
- @DisableFlags(FLAG_ALLOW_ALL_WIDGETS_ON_LOCKSCREEN_BY_DEFAULT)
- @Test
- fun hubShowsKeyguardWidgetsByDefault() =
- testScope.runTest {
- val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER))
- assertThat(setting?.categories)
- .isEqualTo(AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
- }
-
- @EnableFlags(FLAG_COMMUNAL_HUB, FLAG_ALLOW_ALL_WIDGETS_ON_LOCKSCREEN_BY_DEFAULT)
- @Test
- fun hubShowsAllWidgetsByDefaultWhenFlagEnabled() =
- testScope.runTest {
- val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER))
- assertThat(setting?.categories)
- .isEqualTo(
- AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD +
- AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN
- )
- }
-
@Test
fun backgroundType_defaultValue() =
testScope.runTest {
val backgroundType by collectLastValue(underTest.getBackground(PRIMARY_USER))
- assertThat(backgroundType).isEqualTo(CommunalBackgroundType.DEFAULT)
+ assertThat(backgroundType).isEqualTo(CommunalBackgroundType.ANIMATED)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index d951cca..7b26db5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -36,7 +36,6 @@
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.broadcastDispatcher
-import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryImpl
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.FakeCommunalPrefsRepository
import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
@@ -81,7 +80,6 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -915,14 +913,6 @@
)
runCurrent()
- // Keyguard widgets are allowed.
- kosmos.fakeSettings.putIntForUser(
- CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
- AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD,
- mainUser.id
- )
- runCurrent()
-
// When work profile is paused.
whenever(userManager.isQuietModeEnabled(eq(UserHandle.of(USER_INFO_WORK.id))))
.thenReturn(true)
@@ -956,93 +946,6 @@
}
@Test
- fun widgetContent_containsDisabledWidgets_whenCategoryNotAllowed() =
- testScope.runTest {
- // Communal available, and tutorial completed.
- keyguardRepository.setKeyguardShowing(true)
- keyguardRepository.setKeyguardOccluded(false)
- tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-
- val userInfos = listOf(MAIN_USER_INFO, USER_INFO_WORK)
- userRepository.setUserInfos(userInfos)
- userTracker.set(
- userInfos = userInfos,
- selectedUserIndex = 0,
- )
- userRepository.setSelectedUserInfo(MAIN_USER_INFO)
- runCurrent()
-
- // Widgets available.
- val widget1 =
- createWidgetWithCategory(1, AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN)
- val widget2 =
- createWidgetWithCategory(2, AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
- val widget3 =
- createWidgetWithCategory(3, AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX)
- val widgets = listOf(widget1, widget2, widget3)
- widgetRepository.setCommunalWidgets(widgets)
-
- val widgetContent by collectLastValue(underTest.widgetContent)
- kosmos.fakeSettings.putIntForUser(
- CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
- AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD,
- mainUser.id
- )
-
- // Only the keyguard widget is enabled.
- assertThat(widgetContent).hasSize(3)
- assertThat(widgetContent!!.get(0))
- .isInstanceOf(CommunalContentModel.WidgetContent.DisabledWidget::class.java)
- assertThat(widgetContent!!.get(1))
- .isInstanceOf(CommunalContentModel.WidgetContent.Widget::class.java)
- assertThat(widgetContent!!.get(2))
- .isInstanceOf(CommunalContentModel.WidgetContent.DisabledWidget::class.java)
- }
-
- @Test
- fun widgetContent_allEnabled_whenCategoryAllowed() =
- testScope.runTest {
- // Communal available, and tutorial completed.
- keyguardRepository.setKeyguardShowing(true)
- keyguardRepository.setKeyguardOccluded(false)
- tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-
- val userInfos = listOf(MAIN_USER_INFO, USER_INFO_WORK)
- userRepository.setUserInfos(userInfos)
- userTracker.set(
- userInfos = userInfos,
- selectedUserIndex = 0,
- )
- userRepository.setSelectedUserInfo(MAIN_USER_INFO)
- runCurrent()
-
- // Widgets available.
- val widget1 =
- createWidgetWithCategory(1, AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN)
- val widget2 =
- createWidgetWithCategory(2, AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
- val widget3 =
- createWidgetWithCategory(3, AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
- val widgets = listOf(widget1, widget2, widget3)
- widgetRepository.setCommunalWidgets(widgets)
-
- val widgetContent by collectLastValue(underTest.widgetContent)
- kosmos.fakeSettings.putIntForUser(
- CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
- AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD or
- AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
- mainUser.id
- )
-
- // All widgets are enabled.
- assertThat(widgetContent).hasSize(3)
- widgetContent!!.forEach { model ->
- assertThat(model)
- .isInstanceOf(CommunalContentModel.WidgetContent.Widget::class.java)
- }
- }
-
- @Test
fun filterWidgets_whenDisallowedByDevicePolicyForWorkProfile() =
testScope.runTest {
// Keyguard showing, and tutorial completed.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 51991de..d338774 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -69,6 +69,11 @@
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.Transition
+import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.fakeUserTracker
import com.android.systemui.shade.ShadeTestUtil
import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -153,6 +158,7 @@
CommunalViewModel(
kosmos.testDispatcher,
testScope,
+ kosmos.testScope.backgroundScope,
context.resources,
kosmos.keyguardTransitionInteractor,
kosmos.keyguardInteractor,
@@ -491,13 +497,16 @@
flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
)
// Transitioned to Glanceable hub.
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Shade not expanded.
- shadeTestUtil.setLockscreenShadeExpansion(0f)
+ if (!SceneContainerFlag.isEnabled) shadeTestUtil.setLockscreenShadeExpansion(0f)
assertThat(isFocusable).isEqualTo(true)
}
@@ -540,10 +549,13 @@
keyguardRepository.setKeyguardOccluded(true)
// And on hub
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.DREAMING,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.DREAMING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Then flow is not frozen
@@ -557,10 +569,13 @@
assertThat(isCommunalContentFlowFrozen).isEqualTo(true)
// 3. When transitioned to OCCLUDED and activity shows
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ )
)
// Then flow is not frozen
@@ -578,10 +593,13 @@
keyguardRepository.setKeyguardOccluded(false)
// And transitioned to hub
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Then flow is not frozen
@@ -592,30 +610,30 @@
runCurrent()
// And transitioning to occluded
- keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- transitionState = TransitionState.STARTED,
- )
- )
-
- keyguardTransitionRepository.sendTransitionStep(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- transitionState = TransitionState.RUNNING,
- value = 0.5f,
+ kosmos.setTransition(
+ sceneTransition = Transition(from = Scenes.Communal, to = Scenes.Lockscreen),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ transitionState = TransitionState.STARTED,
+ value = 0f,
+ )
)
// Then flow is frozen
assertThat(isCommunalContentFlowFrozen).isEqualTo(true)
// 3. When transition is finished
- keyguardTransitionRepository.sendTransitionStep(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.OCCLUDED,
- transitionState = TransitionState.FINISHED,
- value = 1f,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Lockscreen),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ transitionState = TransitionState.FINISHED,
+ value = 1f,
+ )
)
// Then flow is not frozen
@@ -638,10 +656,13 @@
keyguardRepository.setKeyguardOccluded(true)
// And transitioned to hub
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.DREAMING,
- to = KeyguardState.GLANCEABLE_HUB,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Communal),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.DREAMING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ )
)
// Widgets available
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
index 7b7d03b..7044895 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
@@ -72,6 +72,7 @@
/* animationController = */ notNull(),
/* fillInIntent = */ refEq(fillInIntent),
/* extraOptions = */ refEq(activityOptions.toBundle()),
+ /* customMessage */ isNull(),
)
}
@@ -93,6 +94,7 @@
/* animationController = */ isNull(),
/* fillInIntent = */ refEq(fillInIntent),
/* extraOptions = */ refEq(activityOptions.toBundle()),
+ /* customMessage */ isNull(),
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 84c250c..546510b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -617,6 +617,33 @@
.isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
}
+ @Test
+ fun reportUserPresent_whenDeviceEntered() =
+ testScope.runTest {
+ val isDeviceEntered by collectLastValue(underTest.isDeviceEntered)
+ assertThat(isDeviceEntered).isFalse()
+ assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(0)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
+ switchToScene(Scenes.Gone)
+ assertThat(isDeviceEntered).isTrue()
+ assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(1)
+
+ switchToScene(Scenes.Lockscreen)
+ assertThat(isDeviceEntered).isFalse()
+ assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(1)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ switchToScene(Scenes.Gone)
+ assertThat(isDeviceEntered).isTrue()
+ assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(2)
+ }
+
private fun TestScope.verifyRestrictionReasonsForAuthFlags(
vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?>
) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index c48ced1..86a99e0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -149,6 +149,8 @@
when(mDreamOverlayContainerView.getRootSurfaceControl())
.thenReturn(mAttachedSurfaceControl);
when(mKeyguardTransitionInteractor.isFinishedInStateWhere(any())).thenReturn(emptyFlow());
+ when(mKeyguardTransitionInteractor.isFinishedIn(any(), any())).thenReturn(emptyFlow());
+ when(mKeyguardTransitionInteractor.isFinishedIn(any())).thenReturn(emptyFlow());
when(mShadeInteractor.isAnyExpanded()).thenReturn(MutableStateFlow(false));
when(mCommunalInteractor.isCommunalShowing()).thenReturn(MutableStateFlow(false));
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
index 49d0399..26fcb23 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
@@ -90,7 +90,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = FakeUserTracker(),
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
settings = FakeSettings()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index 9ab1ac1..0f3e78b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -29,7 +29,6 @@
import com.android.systemui.settings.UserFileManager
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -81,7 +80,6 @@
context = context,
userFileManager = userFileManager,
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 159ce36..8e109b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -91,7 +91,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
client1 = FakeCustomizationProviderClient()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 48caf3e..bd6cfff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -20,6 +20,7 @@
import android.hardware.biometrics.BiometricSourceType
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.SysuiTestCase
@@ -73,6 +74,7 @@
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock private lateinit var dreamOverlayCallbackController: DreamOverlayCallbackController
@Mock private lateinit var userTracker: UserTracker
+ @Mock private lateinit var lockPatternUtils: LockPatternUtils
@Captor private lateinit var updateCallbackCaptor: ArgumentCaptor<KeyguardUpdateMonitorCallback>
private val mainDispatcher = StandardTestDispatcher()
private val testDispatcher = StandardTestDispatcher()
@@ -100,6 +102,7 @@
systemClock,
facePropertyRepository,
userTracker,
+ lockPatternUtils,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
index 0792a50..612f2e7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
@@ -34,14 +34,12 @@
import android.os.PowerManager
import android.platform.test.annotations.EnableFlags
-import android.service.dream.dreamManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
-import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -66,10 +64,8 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy
-import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -124,66 +120,6 @@
@Test
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
- fun testTransitionToLockscreen_onWakeup_canDream_glanceableHubAvailable() =
- testScope.runTest {
- whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
- kosmos.setCommunalAvailable(true)
- runCurrent()
-
- powerInteractor.setAwakeForTest()
- runCurrent()
-
- // If dreaming is possible and communal is available, then we should transition to
- // GLANCEABLE_HUB when waking up.
- assertThat(transitionRepository)
- .startedTransition(
- from = KeyguardState.DOZING,
- to = KeyguardState.GLANCEABLE_HUB,
- )
- }
-
- @Test
- @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
- fun testTransitionToLockscreen_onWakeup_canNotDream_glanceableHubAvailable() =
- testScope.runTest {
- whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(false)
- kosmos.setCommunalAvailable(true)
- runCurrent()
-
- powerInteractor.setAwakeForTest()
- runCurrent()
-
- // If dreaming is NOT possible but communal is available, then we should transition to
- // LOCKSCREEN when waking up.
- assertThat(transitionRepository)
- .startedTransition(
- from = KeyguardState.DOZING,
- to = KeyguardState.LOCKSCREEN,
- )
- }
-
- @Test
- @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
- fun testTransitionToLockscreen_onWakeup_canNDream_glanceableHubNotAvailable() =
- testScope.runTest {
- whenever(kosmos.dreamManager.canStartDreaming(anyBoolean())).thenReturn(true)
- kosmos.setCommunalAvailable(false)
- runCurrent()
-
- powerInteractor.setAwakeForTest()
- runCurrent()
-
- // If dreaming is possible but communal is NOT available, then we should transition to
- // LOCKSCREEN when waking up.
- assertThat(transitionRepository)
- .startedTransition(
- from = KeyguardState.DOZING,
- to = KeyguardState.LOCKSCREEN,
- )
- }
-
- @Test
- @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testTransitionToGlanceableHub_onWakeup_ifIdleOnCommunal_noOccludingActivity() =
testScope.runTest {
kosmos.fakeCommunalSceneRepository.setTransitionState(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 78a1167..2d77f4f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -148,7 +148,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
val remoteUserSelectionManager =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
similarity index 92%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
index 9d34903..96b4b43 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
@@ -32,6 +32,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
+import com.android.systemui.shade.pulsingGestureListener
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
@@ -53,14 +54,14 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
-class KeyguardLongPressInteractorTest : SysuiTestCase() {
+class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
private val kosmos =
testKosmos().apply {
this.accessibilityManagerWrapper = mock<AccessibilityManagerWrapper>()
this.uiEventLogger = mock<UiEventLoggerFake>()
}
- private lateinit var underTest: KeyguardLongPressInteractor
+ private lateinit var underTest: KeyguardTouchHandlingInteractor
private val logger = kosmos.uiEventLogger
private val testScope = kosmos.testScope
@@ -209,7 +210,7 @@
underTest.onLongPress()
assertThat(isMenuVisible).isTrue()
- advanceTimeBy(KeyguardLongPressInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
+ advanceTimeBy(KeyguardTouchHandlingInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
assertThat(isMenuVisible).isFalse()
}
@@ -224,11 +225,11 @@
assertThat(isMenuVisible).isTrue()
underTest.onMenuTouchGestureStarted()
- advanceTimeBy(KeyguardLongPressInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
+ advanceTimeBy(KeyguardTouchHandlingInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
assertThat(isMenuVisible).isTrue()
underTest.onMenuTouchGestureEnded(/* isClick= */ false)
- advanceTimeBy(KeyguardLongPressInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
+ advanceTimeBy(KeyguardTouchHandlingInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
assertThat(isMenuVisible).isFalse()
}
@@ -241,7 +242,7 @@
underTest.onLongPress()
verify(logger)
- .log(KeyguardLongPressInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN)
+ .log(KeyguardTouchHandlingInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN)
}
@Test
@@ -254,7 +255,7 @@
underTest.onMenuTouchGestureEnded(/* isClick= */ true)
verify(logger)
- .log(KeyguardLongPressInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED)
+ .log(KeyguardTouchHandlingInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED)
}
@Test
@@ -288,7 +289,7 @@
// This needs to be re-created for each test outside of kosmos since the flag values are
// read during initialization to set up flows. Maybe there is a better way to handle that.
underTest =
- KeyguardLongPressInteractor(
+ KeyguardTouchHandlingInteractor(
appContext = mContext,
scope = testScope.backgroundScope,
transitionInteractor = kosmos.keyguardTransitionInteractor,
@@ -300,7 +301,8 @@
set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, isOpenWppDirectlyEnabled)
},
broadcastDispatcher = fakeBroadcastDispatcher,
- accessibilityManager = kosmos.accessibilityManagerWrapper
+ accessibilityManager = kosmos.accessibilityManagerWrapper,
+ pulsingGestureListener = kosmos.pulsingGestureListener,
)
setUpState()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 0f061de..40918a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -1097,9 +1097,10 @@
}
@Test
+ @DisableSceneContainer
fun isFinishedInState() =
testScope.runTest {
- val results by collectValues(underTest.isFinishedInState(GONE))
+ val results by collectValues(underTest.isFinishedIn(Scenes.Gone, GONE))
sendSteps(
TransitionStep(AOD, DOZING, 0f, STARTED),
@@ -1194,6 +1195,89 @@
}
@Test
+ @EnableSceneContainer
+ fun isFinishedIn() =
+ testScope.runTest {
+ val results by collectValues(underTest.isFinishedIn(Scenes.Gone, GONE))
+
+ sendSteps(
+ TransitionStep(AOD, DOZING, 0f, STARTED),
+ TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+ TransitionStep(AOD, DOZING, 1f, FINISHED),
+ )
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false, // Finished in DOZING, not GONE.
+ )
+ )
+
+ kosmos.setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ )
+ )
+
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ true,
+ )
+ )
+
+ kosmos.setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ true,
+ )
+ )
+
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ true,
+ false,
+ )
+ )
+
+ kosmos.setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ true,
+ false,
+ )
+ )
+
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+ assertThat(results)
+ .isEqualTo(
+ listOf(
+ false,
+ true,
+ false,
+ true,
+ )
+ )
+ }
+
+ @Test
fun finishedKeyguardState_emitsAgainIfCancelledAndReversed() =
testScope.runTest {
val finishedStates by collectValues(underTest.finishedKeyguardState)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt
new file mode 100644
index 0000000..f1ffe66
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.shared.model
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyguardStateTest : SysuiTestCase() {
+
+ /**
+ * This test makes sure that the result of [deviceIsAwakeInState] are equal for all the states
+ * that are obsolete with scene container enabled and UNDEFINED. This means for example that if
+ * GONE is transformed to UNDEFINED it makes sure that GONE and UNDEFINED need to have the same
+ * value. This assumption is important as with scene container flag enabled call sites will only
+ * check the result passing in UNDEFINED.
+ *
+ * This is true today, but as more states may become obsolete this assumption may not be true
+ * anymore and therefore [deviceIsAwakeInState] would need to be rewritten to factor in the
+ * scene state.
+ */
+ @Test
+ @EnableSceneContainer
+ fun assertUndefinedResultMatchesObsoleteStateResults() {
+ for (state in KeyguardState.entries) {
+ val isAwakeInSceneContainer =
+ KeyguardState.deviceIsAwakeInState(state.mapToSceneContainerState())
+ val isAwake = KeyguardState.deviceIsAwakeInState(state)
+ assertThat(isAwakeInSceneContainer).isEqualTo(isAwake)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 61d8216..4eb146d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -19,6 +19,7 @@
package com.android.systemui.keyguard.ui.viewmodel
import android.platform.test.annotations.EnableFlags
+import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.SceneKey
@@ -61,6 +62,7 @@
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
+@RunWithLooper
@EnableSceneContainer
class LockscreenSceneViewModelTest : SysuiTestCase() {
@@ -265,8 +267,8 @@
applicationScope = testScope.backgroundScope,
deviceEntryInteractor = kosmos.deviceEntryInteractor,
communalInteractor = kosmos.communalInteractor,
- longPress =
- KeyguardLongPressViewModel(
+ touchHandling =
+ KeyguardTouchHandlingViewModel(
interactor = mock(),
),
notifications = kosmos.notificationsPlaceholderViewModel,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/data/QSPreferencesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/panels/data/QSPreferencesRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
index 7c95dfe..8ac5b6c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/data/QSPreferencesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.data
+package com.android.systemui.qs.panels.data.repository
import android.content.Context
import android.content.SharedPreferences
@@ -24,8 +24,6 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.panels.data.repository.QSPreferencesRepository
-import com.android.systemui.qs.panels.data.repository.qsPreferencesRepository
import com.android.systemui.settings.userFileManager
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.fakeUserRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt
new file mode 100644
index 0000000..ae6f576
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QuickQuickSettingsRowRepositoryTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+
+ private val underTest = kosmos.quickQuickSettingsRowRepository
+
+ @Test
+ fun rows_followsConfig() =
+ with(kosmos) {
+ testScope.runTest {
+ val rows by collectLastValue(underTest.rows)
+
+ setRowsInConfig(2)
+ assertThat(rows).isEqualTo(2)
+
+ setRowsInConfig(3)
+ assertThat(rows).isEqualTo(3)
+ }
+ }
+
+ private fun setRowsInConfig(rows: Int) =
+ with(kosmos) {
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_qs_panel_max_rows,
+ rows,
+ )
+ fakeConfigurationRepository.onConfigurationChange()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
new file mode 100644
index 0000000..1c3021e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.compose
+
+import androidx.compose.runtime.mutableStateOf
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DragAndDropStateTest : SysuiTestCase() {
+ private val listState = EditTileListState(TestEditTiles)
+ private val underTest = DragAndDropState(mutableStateOf(null), listState)
+
+ @Test
+ fun isMoving_returnsCorrectValue() {
+ // Asserts no tiles is moving
+ TestEditTiles.forEach { assertThat(underTest.isMoving(it.tileSpec)).isFalse() }
+
+ // Start the drag movement
+ val movingTileSpec = TestEditTiles[0].tileSpec
+ underTest.onStarted(movingTileSpec)
+
+ // Assert that the correct tile is marked as moving
+ TestEditTiles.forEach {
+ assertThat(underTest.isMoving(it.tileSpec)).isEqualTo(movingTileSpec == it.tileSpec)
+ }
+ }
+
+ @Test
+ fun onMoved_updatesList() {
+ val movingTileSpec = TestEditTiles[0].tileSpec
+
+ // Start the drag movement
+ underTest.onStarted(movingTileSpec)
+
+ // Move the tile to the end of the list
+ underTest.onMoved(listState.tiles[5].tileSpec)
+ assertThat(underTest.currentPosition()).isEqualTo(5)
+
+ // Move the tile to the middle of the list
+ underTest.onMoved(listState.tiles[2].tileSpec)
+ assertThat(underTest.currentPosition()).isEqualTo(2)
+ }
+
+ @Test
+ fun onDrop_resetsMovingTile() {
+ val movingTileSpec = TestEditTiles[0].tileSpec
+
+ // Start the drag movement
+ underTest.onStarted(movingTileSpec)
+
+ // Move the tile to the end of the list
+ underTest.onMoved(listState.tiles[5].tileSpec)
+
+ // Drop the tile
+ underTest.onDrop()
+
+ // Asserts no tiles is moving
+ TestEditTiles.forEach { assertThat(underTest.isMoving(it.tileSpec)).isFalse() }
+ }
+
+ companion object {
+ private fun createEditTile(tileSpec: String): EditTileViewModel {
+ return EditTileViewModel(
+ tileSpec = TileSpec.create(tileSpec),
+ icon = Icon.Resource(0, null),
+ label = Text.Loaded("unused"),
+ appName = null,
+ isCurrent = true,
+ availableEditActions = emptySet(),
+ )
+ }
+
+ private val TestEditTiles =
+ listOf(
+ createEditTile("tileA"),
+ createEditTile("tileB"),
+ createEditTile("tileC"),
+ createEditTile("tileD"),
+ createEditTile("tileE"),
+ createEditTile("tileF"),
+ )
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
new file mode 100644
index 0000000..517b601
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.compose
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class EditTileListStateTest : SysuiTestCase() {
+ val underTest = EditTileListState(TestEditTiles)
+
+ @Test
+ fun movingNonExistentTile_listUnchanged() {
+ underTest.move(TileSpec.create("other_tile"), TestEditTiles[0].tileSpec)
+
+ assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
+ }
+
+ @Test
+ fun movingTileToNonExistentTarget_listUnchanged() {
+ underTest.move(TestEditTiles[0].tileSpec, TileSpec.create("other_tile"))
+
+ assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
+ }
+
+ @Test
+ fun movingTileToItself_listUnchanged() {
+ underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[0].tileSpec)
+
+ assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
+ }
+
+ @Test
+ fun movingTileToSameSection_listUpdates() {
+ // Move tile at index 0 to index 1. Tile 0 should remain current.
+ underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[1].tileSpec)
+
+ // Assert the tiles 0 and 1 have changed places.
+ assertThat(underTest.tiles[0]).isEqualTo(TestEditTiles[1])
+ assertThat(underTest.tiles[1]).isEqualTo(TestEditTiles[0])
+
+ // Assert the rest of the list is unchanged
+ assertThat(underTest.tiles.subList(2, 5))
+ .containsExactly(*TestEditTiles.subList(2, 5).toTypedArray())
+ }
+
+ @Test
+ fun movingTileToDifferentSection_listAndTileUpdates() {
+ // Move tile at index 0 to index 3. Tile 0 should no longer be current.
+ underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[3].tileSpec)
+
+ // Assert tile 0 is now at index 3 and is no longer current.
+ assertThat(underTest.tiles[3]).isEqualTo(TestEditTiles[0].copy(isCurrent = false))
+
+ // Assert previous tiles have shifted places
+ assertThat(underTest.tiles[0]).isEqualTo(TestEditTiles[1])
+ assertThat(underTest.tiles[1]).isEqualTo(TestEditTiles[2])
+ assertThat(underTest.tiles[2]).isEqualTo(TestEditTiles[3])
+
+ // Assert the rest of the list is unchanged
+ assertThat(underTest.tiles.subList(4, 5))
+ .containsExactly(*TestEditTiles.subList(4, 5).toTypedArray())
+ }
+
+ companion object {
+ private fun createEditTile(tileSpec: String, isCurrent: Boolean): EditTileViewModel {
+ return EditTileViewModel(
+ tileSpec = TileSpec.create(tileSpec),
+ icon = Icon.Resource(0, null),
+ label = Text.Loaded("unused"),
+ appName = null,
+ isCurrent = isCurrent,
+ availableEditActions = emptySet(),
+ )
+ }
+
+ private val TestEditTiles =
+ listOf(
+ createEditTile("tileA", true),
+ createEditTile("tileB", true),
+ createEditTile("tileC", true),
+ createEditTile("tileD", false),
+ createEditTile("tileE", false),
+ createEditTile("tileF", false),
+ )
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
new file mode 100644
index 0000000..d36a81b
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.data.repository.IconTilesRepository
+import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QuickQuickSettingsViewModelTest : SysuiTestCase() {
+
+ private val kosmos =
+ testKosmos().apply {
+ iconTilesRepository =
+ object : IconTilesRepository {
+ override fun isIconTile(spec: TileSpec): Boolean {
+ return spec.spec.startsWith(PREFIX_SMALL)
+ }
+ }
+ }
+
+ private val underTest = kosmos.quickQuickSettingsViewModel
+
+ private val tiles =
+ listOf(
+ "$PREFIX_SMALL:1",
+ "$PREFIX_SMALL:2",
+ "$PREFIX_LARGE:3",
+ "$PREFIX_SMALL:4",
+ "$PREFIX_LARGE:5",
+ "$PREFIX_LARGE:6",
+ "$PREFIX_SMALL:7",
+ "$PREFIX_SMALL:8",
+ "$PREFIX_LARGE:9",
+ )
+ .map(TileSpec::create)
+
+ @Before
+ fun setUp() {
+ kosmos.setTiles(tiles)
+ }
+
+ @Test
+ fun splitIntoRows_onlyFirstTwoRowsOfTiles() =
+ with(kosmos) {
+ testScope.runTest {
+ setRows(2)
+ val columns by collectLastValue(underTest.columns)
+ val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+ assertThat(columns).isEqualTo(4)
+ // All tiles in 4 columns
+ // [1] [2] [3 3]
+ // [4] [5 5]
+ // [6 6] [7] [8]
+ // [9 9]
+
+ assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(5))
+ }
+ }
+
+ @Test
+ fun changeRows_tilesChange() =
+ with(kosmos) {
+ testScope.runTest {
+ setRows(2)
+ val columns by collectLastValue(underTest.columns)
+ val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+ assertThat(columns).isEqualTo(4)
+ // All tiles in 4 columns
+ // [1] [2] [3 3]
+ // [4] [5 5]
+ // [6 6] [7] [8]
+ // [9 9]
+
+ setRows(3)
+ assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(8))
+ setRows(1)
+ assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(3))
+ }
+ }
+
+ @Test
+ fun changeTiles_tilesChange() =
+ with(kosmos) {
+ testScope.runTest {
+ setRows(2)
+ val columns by collectLastValue(underTest.columns)
+ val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+ assertThat(columns).isEqualTo(4)
+ // All tiles in 4 columns
+ // [1] [2] [3 3]
+ // [4] [5 5]
+ // [6 6] [7] [8]
+ // [9 9]
+
+ // Remove tile small:4
+ currentTilesInteractor.removeTiles(setOf(tiles[3]))
+
+ assertThat(tileViewModels!!.map { it.tile.spec })
+ .isEqualTo(
+ listOf(
+ "$PREFIX_SMALL:1",
+ "$PREFIX_SMALL:2",
+ "$PREFIX_LARGE:3",
+ "$PREFIX_LARGE:5",
+ "$PREFIX_LARGE:6",
+ )
+ .map(TileSpec::create)
+ )
+ }
+ }
+
+ private fun Kosmos.setTiles(tiles: List<TileSpec>) {
+ currentTilesInteractor.setTiles(tiles)
+ }
+
+ private fun Kosmos.setRows(rows: Int) {
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_qs_panel_max_rows,
+ rows,
+ )
+ fakeConfigurationRepository.onConfigurationChange()
+ }
+
+ private companion object {
+ const val PREFIX_SMALL = "small"
+ const val PREFIX_LARGE = "large"
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
index 9ce2e0f..c33e2a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
@@ -92,7 +92,8 @@
runCurrent()
assertThat(states()).isNotEmpty()
- assertThat(states().first().label).isEqualTo(testTileData)
+ assertThat(states().last()).isNotNull()
+ assertThat(states().last()!!.label).isEqualTo(testTileData)
verify(qsTileLogger).logInitialRequest(eq(tileConfig.tileSpec))
}
@@ -196,6 +197,7 @@
qsTileLogger,
FakeSystemClock(),
testCoroutineDispatcher,
+ testCoroutineDispatcher,
scope.backgroundScope,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
index 6066d24..7955f2f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
@@ -256,6 +256,7 @@
qsTileLogger,
FakeSystemClock(),
testCoroutineDispatcher,
+ testCoroutineDispatcher,
scope.backgroundScope,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index e01ffa6..9249621 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.ui.viewmodel
+import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Back
@@ -65,6 +66,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@RunWithLooper
@EnableSceneContainer
class QuickSettingsSceneViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
index 411a7a4..a7a3a0f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
@@ -19,6 +19,7 @@
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
@@ -31,12 +32,12 @@
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.fakeShadeRepository
-import com.android.systemui.shade.ui.viewmodel.quickSettingsShadeSceneViewModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -155,6 +156,24 @@
assertThat(homeScene).isEqualTo(Scenes.Gone)
}
+ @Test
+ fun backTransitionSceneKey_notEditing_Home() =
+ testScope.runTest {
+ val destinationScenes by collectLastValue(underTest.destinationScenes)
+
+ assertThat(destinationScenes?.get(Back)?.toScene).isEqualTo(SceneFamilies.Home)
+ }
+
+ @Test
+ fun backTransition_editing_noDestination() =
+ testScope.runTest {
+ val destinationScenes by collectLastValue(underTest.destinationScenes)
+ kosmos.editModeViewModel.startEditing()
+
+ assertThat(destinationScenes!!).isNotEmpty()
+ assertThat(destinationScenes?.get(Back)).isNull()
+ }
+
private fun TestScope.lockDevice() {
val deviceUnlockStatus by collectLastValue(deviceUnlockedInteractor.deviceUnlockStatus)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 412505d..39b3662 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -48,16 +48,13 @@
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
-import com.android.systemui.qs.footerActionsController
-import com.android.systemui.qs.footerActionsViewModelFactory
-import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
+import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
import com.android.systemui.scene.domain.startable.sceneContainerStartable
@@ -65,16 +62,14 @@
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
-import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
-import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModel
+import com.android.systemui.shade.ui.viewmodel.shadeSceneViewModel
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
import com.android.systemui.telephony.data.repository.fakeTelephonyRepository
import com.android.systemui.testKosmos
-import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -138,7 +133,6 @@
sceneInteractor = sceneInteractor,
falsingInteractor = kosmos.falsingInteractor,
powerInteractor = kosmos.powerInteractor,
- scenes = kosmos.scenes,
)
.apply { setTransitionState(transitionState) }
}
@@ -152,8 +146,8 @@
applicationScope = testScope.backgroundScope,
deviceEntryInteractor = deviceEntryInteractor,
communalInteractor = communalInteractor,
- longPress =
- KeyguardLongPressViewModel(
+ touchHandling =
+ KeyguardTouchHandlingViewModel(
interactor = mock(),
),
notifications = kosmos.notificationsPlaceholderViewModel,
@@ -167,7 +161,7 @@
private var bouncerSceneJob: Job? = null
- private val qsFlexiglassAdapter = FakeQSSceneAdapter(inflateDelegate = { mock() })
+ private val qsFlexiglassAdapter = kosmos.fakeQSSceneAdapter
private lateinit var emergencyAffordanceManager: EmergencyAffordanceManager
private lateinit var telecomManager: TelecomManager
@@ -200,20 +194,7 @@
bouncerActionButtonInteractor = kosmos.bouncerActionButtonInteractor
bouncerViewModel = kosmos.bouncerViewModel
- shadeSceneViewModel =
- ShadeSceneViewModel(
- applicationScope = testScope.backgroundScope,
- shadeHeaderViewModel = kosmos.shadeHeaderViewModel,
- qsSceneAdapter = qsFlexiglassAdapter,
- notifications = kosmos.notificationsPlaceholderViewModel,
- brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel,
- mediaCarouselInteractor = kosmos.mediaCarouselInteractor,
- shadeInteractor = kosmos.shadeInteractor,
- footerActionsController = kosmos.footerActionsController,
- footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
- sceneInteractor = sceneInteractor,
- unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor,
- )
+ shadeSceneViewModel = kosmos.shadeSceneViewModel
val startable = kosmos.sceneContainerStartable
startable.start()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index ae615dd..fd1b213 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -26,14 +26,18 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.internal.logging.uiEventLoggerFake
+import com.android.internal.policy.IKeyguardDismissCallback
import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
+import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.bouncer.shared.logging.BouncerUiEvent
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.classifier.falsingCollector
import com.android.systemui.classifier.falsingManager
+import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -44,7 +48,13 @@
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeTrustRepository
+import com.android.systemui.keyguard.data.repository.keyguardRepository
+import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
+import com.android.systemui.keyguard.dismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.scenetransition.lockscreenSceneTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.model.sysUiState
@@ -54,6 +64,7 @@
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
+import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
@@ -386,6 +397,64 @@
}
@Test
+ fun switchToAOD_whenAvailable_whenDeviceSleepsLocked() =
+ testScope.runTest {
+ kosmos.lockscreenSceneTransitionInteractor.start()
+ val asleepState by
+ collectLastValue(kosmos.keyguardTransitionInteractor.asleepKeyguardState)
+ val currentTransitionInfo by
+ collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal)
+ val transitionState =
+ prepareState(
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Shade,
+ )
+ kosmos.keyguardRepository.setAodAvailable(true)
+ runCurrent()
+ assertThat(asleepState).isEqualTo(KeyguardState.AOD)
+ underTest.start()
+ powerInteractor.setAsleepForTest()
+ runCurrent()
+ transitionState.value =
+ ObservableTransitionState.Transition(
+ fromScene = Scenes.Shade,
+ toScene = Scenes.Lockscreen,
+ currentScene = flowOf(Scenes.Lockscreen),
+ progress = flowOf(0.5f),
+ isInitiatedByUserInput = true,
+ isUserInputOngoing = flowOf(false),
+ )
+ runCurrent()
+
+ assertThat(currentTransitionInfo?.to).isEqualTo(KeyguardState.AOD)
+ }
+
+ @Test
+ fun switchToDozing_whenAodUnavailable_whenDeviceSleepsLocked() =
+ testScope.runTest {
+ kosmos.lockscreenSceneTransitionInteractor.start()
+ val asleepState by
+ collectLastValue(kosmos.keyguardTransitionInteractor.asleepKeyguardState)
+ val currentTransitionInfo by
+ collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal)
+ val transitionState =
+ prepareState(
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Shade,
+ )
+ kosmos.keyguardRepository.setAodAvailable(false)
+ runCurrent()
+ assertThat(asleepState).isEqualTo(KeyguardState.DOZING)
+ underTest.start()
+ powerInteractor.setAsleepForTest()
+ runCurrent()
+ transitionState.value = Transition(from = Scenes.Shade, to = Scenes.Lockscreen)
+ runCurrent()
+
+ assertThat(currentTransitionInfo?.to).isEqualTo(KeyguardState.DOZING)
+ }
+
+ @Test
fun switchToGoneWhenDoubleTapPowerGestureIsTriggeredFromGone() =
testScope.runTest {
val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
@@ -404,15 +473,7 @@
lastSleepReason = WakeSleepReason.POWER_BUTTON,
powerButtonLaunchGestureTriggered = false,
)
- transitionStateFlow.value =
- ObservableTransitionState.Transition(
- fromScene = Scenes.Gone,
- toScene = Scenes.Lockscreen,
- currentScene = flowOf(Scenes.Lockscreen),
- progress = flowOf(0.5f),
- isInitiatedByUserInput = true,
- isUserInputOngoing = flowOf(false),
- )
+ transitionStateFlow.value = Transition(from = Scenes.Shade, to = Scenes.Lockscreen)
assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
kosmos.fakePowerRepository.updateWakefulness(
@@ -486,6 +547,11 @@
QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0L
)
.isFalse()
+ assertThat(
+ sysUiState.flags and
+ QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED != 0L
+ )
+ .isFalse()
kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(false)
runCurrent()
@@ -499,6 +565,11 @@
QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0L
)
.isTrue()
+ assertThat(
+ sysUiState.flags and
+ QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED != 0L
+ )
+ .isTrue()
}
@Test
@@ -1447,6 +1518,47 @@
assertThat(currentScene).isEqualTo(Scenes.Gone)
}
+ @Test
+ fun notifyKeyguardDismissCallbacks_whenUnlocking_onDismissSucceeded() =
+ testScope.runTest {
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ prepareState()
+ underTest.start()
+ val dismissCallback: IKeyguardDismissCallback = mock()
+ kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
+
+ // Switch to bouncer and unlock device:
+ sceneInteractor.changeScene(Scenes.Bouncer, "")
+ assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+ kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
+ kosmos.fakeExecutor.runAllReady()
+
+ verify(dismissCallback).onDismissSucceeded()
+ }
+
+ @Test
+ fun notifyKeyguardDismissCallbacks_whenLeavingBouncer_onDismissCancelled() =
+ testScope.runTest {
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ prepareState()
+ underTest.start()
+ val dismissCallback: IKeyguardDismissCallback = mock()
+ kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
+
+ // Switch to bouncer:
+ sceneInteractor.changeScene(Scenes.Bouncer, "")
+ assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+
+ // Return to lockscreen:
+ sceneInteractor.changeScene(Scenes.Lockscreen, "")
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ runCurrent()
+ kosmos.fakeExecutor.runAllReady()
+
+ verify(dismissCallback).onDismissCancelled()
+ }
+
private fun TestScope.emulateSceneTransition(
transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
toScene: SceneKey,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index 5c30379..ea95aab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -28,10 +28,8 @@
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.fakeScenes
import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.scenes
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
@@ -66,7 +64,6 @@
sceneInteractor = sceneInteractor,
falsingInteractor = kosmos.falsingInteractor,
powerInteractor = kosmos.powerInteractor,
- scenes = kosmos.scenes,
)
}
@@ -217,23 +214,4 @@
assertThat(isVisible).isFalse()
}
-
- @Test
- fun currentDestinationScenes_onlyTheCurrentSceneIsCollected() =
- testScope.runTest {
- val unused by collectLastValue(underTest.currentDestinationScenes(backgroundScope))
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- kosmos.fakeScenes.forEach { scene ->
- fakeSceneDataSource.changeScene(toScene = scene.key)
- runCurrent()
- assertThat(currentScene).isEqualTo(scene.key)
-
- assertThat(scene.isDestinationScenesBeingCollected).isTrue()
- kosmos.fakeScenes
- .filter { it.key != scene.key }
- .forEach { otherScene ->
- assertThat(otherScene.isDestinationScenesBeingCollected).isFalse()
- }
- }
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt
index 6de7f40..13b61bc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt
@@ -68,4 +68,27 @@
Assert.setTestThread(null)
}
+
+ @Test
+ fun inflate_frameHasPadding() {
+ Assert.setTestThread(Thread.currentThread())
+
+ val (frame, _) =
+ BrightnessMirrorInflater.inflate(
+ themedContext,
+ kosmos.brightnessSliderControllerFactory,
+ )
+
+ assertThat(frame.visibility).isEqualTo(View.VISIBLE)
+
+ val padding =
+ context.resources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding)
+
+ assertThat(frame.paddingLeft).isEqualTo(padding)
+ assertThat(frame.paddingTop).isEqualTo(padding)
+ assertThat(frame.paddingRight).isEqualTo(padding)
+ assertThat(frame.paddingBottom).isEqualTo(padding)
+
+ Assert.setTestThread(null)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt
index 09fc6f9..90c11d4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt
@@ -16,10 +16,9 @@
package com.android.systemui.settings.brightness.ui.viewmodel
-import android.content.applicationContext
import android.content.res.mainResources
-import android.view.ContextThemeWrapper
import android.view.View
+import android.widget.FrameLayout
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -27,12 +26,10 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
-import com.android.systemui.settings.brightness.ui.binder.BrightnessMirrorInflater
import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
import com.android.systemui.settings.brightness.ui.viewModel.LocationAndSize
import com.android.systemui.settings.brightnessSliderControllerFactory
import com.android.systemui.testKosmos
-import com.android.systemui.util.Assert
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -47,9 +44,6 @@
private val kosmos = testKosmos()
- private val themedContext =
- ContextThemeWrapper(kosmos.applicationContext, R.style.Theme_SystemUI_QuickSettings)
-
private val underTest =
with(kosmos) {
BrightnessMirrorViewModel(
@@ -76,7 +70,7 @@
}
@Test
- fun setLocationInWindow_correctLocationAndSize() =
+ fun locationInWindowAndContainer_correctLocationAndSize() =
with(kosmos) {
testScope.runTest {
val locationAndSize by collectLastValue(underTest.locationAndSize)
@@ -101,6 +95,7 @@
whenever(measuredHeight).thenReturn(height)
whenever(measuredWidth).thenReturn(width)
}
+ val yOffsetFromContainer = setContainerViewHierarchy(mockView)
underTest.setLocationAndSize(mockView)
@@ -108,7 +103,8 @@
.isEqualTo(
// Adjust for padding around the view
LocationAndSize(
- yOffset = y - padding,
+ yOffsetFromWindow = y - padding,
+ yOffsetFromContainer = yOffsetFromContainer - padding,
width = width + 2 * padding,
height = height + 2 * padding,
)
@@ -116,31 +112,20 @@
}
}
- @Test
- fun setLocationInWindow_paddingSetToRootView() =
- with(kosmos) {
- Assert.setTestThread(Thread.currentThread())
- val padding =
- mainResources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding)
+ private fun setContainerViewHierarchy(mockView: View): Int {
+ val rootView = FrameLayout(context)
+ val containerView = FrameLayout(context).apply { id = R.id.quick_settings_container }
+ val otherView = FrameLayout(context)
- val view = mock<View>()
+ rootView.addView(containerView)
+ containerView.addView(otherView)
+ otherView.addView(mockView)
- val (_, sliderController) =
- BrightnessMirrorInflater.inflate(
- themedContext,
- brightnessSliderControllerFactory,
- )
- underTest.setToggleSlider(sliderController)
+ containerView.setLeftTopRightBottom(1, /* top= */ 1, 1, 1)
+ otherView.setLeftTopRightBottom(0, /* top= */ 2, 0, 0)
+ whenever(mockView.parent).thenReturn(otherView)
+ whenever(mockView.top).thenReturn(3)
- underTest.setLocationAndSize(view)
-
- with(sliderController.rootView) {
- assertThat(paddingBottom).isEqualTo(padding)
- assertThat(paddingTop).isEqualTo(padding)
- assertThat(paddingLeft).isEqualTo(padding)
- assertThat(paddingRight).isEqualTo(padding)
- }
-
- Assert.setTestThread(null)
- }
+ return 2 + 3
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index a0295c9..673d5ef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -36,28 +36,20 @@
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
-import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.shared.model.MediaData
-import com.android.systemui.qs.footerActionsController
-import com.android.systemui.qs.footerActionsViewModelFactory
-import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
+import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter
+import com.android.systemui.qs.ui.adapter.qsSceneAdapter
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
-import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.domain.startable.shadeStartable
import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
import com.android.systemui.testKosmos
-import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
-import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -66,11 +58,8 @@
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -83,32 +72,9 @@
private val testScope = kosmos.testScope
private val sceneInteractor by lazy { kosmos.sceneInteractor }
private val shadeRepository by lazy { kosmos.shadeRepository }
+ private val qsSceneAdapter by lazy { kosmos.fakeQSSceneAdapter }
- private val qsSceneAdapter = FakeQSSceneAdapter({ mock() })
-
- private lateinit var underTest: ShadeSceneViewModel
-
- @Mock private lateinit var mediaDataManager: MediaDataManager
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
-
- underTest =
- ShadeSceneViewModel(
- applicationScope = testScope.backgroundScope,
- shadeHeaderViewModel = kosmos.shadeHeaderViewModel,
- qsSceneAdapter = qsSceneAdapter,
- notifications = kosmos.notificationsPlaceholderViewModel,
- brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel,
- mediaCarouselInteractor = kosmos.mediaCarouselInteractor,
- shadeInteractor = kosmos.shadeInteractor,
- footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
- footerActionsController = kosmos.footerActionsController,
- sceneInteractor = kosmos.sceneInteractor,
- unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor,
- )
- }
+ private val underTest: ShadeSceneViewModel by lazy { kosmos.shadeSceneViewModel }
@Test
fun upTransitionSceneKey_deviceLocked_lockScreen() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index f06e04b..355669b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -38,11 +38,16 @@
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.kotlin.JavaAdapter
import com.android.systemui.util.mockito.mock
@@ -105,6 +110,7 @@
{ kosmos.shadeInteractor },
{ kosmos.deviceUnlockedInteractor },
{ kosmos.sceneInteractor },
+ { kosmos.sceneContainerOcclusionInteractor },
{ kosmos.keyguardClockInteractor },
) {
override fun createDarkAnimator(): ObjectAnimator {
@@ -336,6 +342,47 @@
}
@Test
+ @EnableSceneContainer
+ fun start_hydratesStatusBarState_whileOccluded() =
+ testScope.runTest {
+ var statusBarState = underTest.state
+ val listener =
+ object : StatusBarStateController.StateListener {
+ override fun onStateChanged(newState: Int) {
+ statusBarState = newState
+ }
+ }
+ underTest.addCallback(listener)
+
+ val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ val isOccluded by
+ collectLastValue(kosmos.sceneContainerOcclusionInteractor.invisibleDueToOcclusion)
+ kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(
+ showWhenLockedActivityOnTop = true,
+ taskInfo = mock(),
+ )
+ runCurrent()
+ assertThat(isOccluded).isTrue()
+
+ // Call start to begin hydrating based on the scene framework:
+ underTest.start()
+
+ kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason")
+ runCurrent()
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
+ assertThat(statusBarState).isEqualTo(StatusBarState.SHADE)
+
+ kosmos.sceneInteractor.changeScene(
+ toScene = Scenes.QuickSettings,
+ loggingReason = "reason"
+ )
+ runCurrent()
+ assertThat(currentScene).isEqualTo(Scenes.QuickSettings)
+ assertThat(statusBarState).isEqualTo(StatusBarState.SHADE)
+ }
+
+ @Test
fun leaveOpenOnKeyguard_whenGone_isFalse() =
testScope.runTest {
underTest.start()
@@ -348,11 +395,15 @@
)
assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(true)
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.GONE,
- testScope = testScope,
+ kosmos.setTransition(
+ sceneTransition = Idle(Scenes.Gone),
+ stateTransition =
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ )
)
+
assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(false)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
index cc3fdc5..23b28e3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
@@ -18,6 +18,7 @@
package com.android.systemui.statusbar.notification
+import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
@@ -48,6 +49,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@RunWithLooper
@EnableSceneContainer
class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
@@ -171,6 +173,22 @@
}
@Test
+ fun shadeExpansion_idleOnQs() =
+ testScope.runTest {
+ val transitionState =
+ MutableStateFlow<ObservableTransitionState>(
+ ObservableTransitionState.Idle(currentScene = Scenes.QuickSettings)
+ )
+ sceneInteractor.setTransitionState(transitionState)
+ val expandFraction by collectLastValue(scrollViewModel.expandFraction)
+ assertThat(expandFraction).isEqualTo(1f)
+
+ fakeSceneDataSource.changeScene(toScene = Scenes.QuickSettings)
+ val isScrollable by collectLastValue(scrollViewModel.isScrollable)
+ assertThat(isScrollable).isFalse()
+ }
+
+ @Test
fun shadeExpansion_shadeToQs() =
testScope.runTest {
val transitionState =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
index ee9fd349..4944c8b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -31,9 +32,10 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@RunWithLooper
class NotificationsPlaceholderViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
- private val underTest = kosmos.notificationsPlaceholderViewModel
+ private val underTest by lazy { kosmos.notificationsPlaceholderViewModel }
@Test
fun onBoundsChanged() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
index 5887f90..ccd78ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
@@ -154,6 +154,25 @@
}
@Test
+ fun startPendingIntentDismissingKeyguard_withCustomMessage_dismissWithAction() {
+ val pendingIntent = mock(PendingIntent::class.java)
+ `when`(pendingIntent.isActivity).thenReturn(true)
+ `when`(keyguardStateController.isShowing).thenReturn(true)
+ `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ val customMessage = "Custom unlock reason"
+
+ underTest.startPendingIntentDismissingKeyguard(
+ intent = pendingIntent,
+ dismissShade = true,
+ customMessage = customMessage
+ )
+ mainExecutor.runAllReady()
+
+ verify(statusBarKeyguardViewManager)
+ .dismissWithAction(any(), eq(null), anyBoolean(), eq(customMessage))
+ }
+
+ @Test
fun startPendingIntentMaybeDismissingKeyguard_keyguardShowing_showOverLs_launchAnimator() {
val pendingIntent = mock(PendingIntent::class.java)
val parent = FrameLayout(context)
@@ -466,6 +485,7 @@
animationController: ActivityTransitionAnimator.Controller?,
fillInIntent: Intent? = null,
extraOptions: Bundle? = null,
+ customMessage: String? = null,
) {
underTest.startPendingIntentDismissingKeyguard(
intent = intent,
@@ -475,6 +495,7 @@
showOverLockscreen = true,
fillInIntent = fillInIntent,
extraOptions = extraOptions,
+ customMessage = customMessage,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
index 200e92e..7346323 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.os.Handler;
import android.platform.test.flag.junit.FlagsParameterization;
import android.testing.TestableLooper;
@@ -85,6 +86,8 @@
@Mock private DumpManager dumpManager;
private AvalancheController mAvalancheController;
+ @Mock private Handler mBgHandler;
+
private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
TestableHeadsUpManagerPhone(
Context context,
@@ -101,7 +104,8 @@
UiEventLogger uiEventLogger,
JavaAdapter javaAdapter,
ShadeInteractor shadeInteractor,
- AvalancheController avalancheController
+ AvalancheController avalancheController,
+ Handler bgHandler
) {
super(
context,
@@ -119,7 +123,8 @@
uiEventLogger,
javaAdapter,
shadeInteractor,
- avalancheController
+ avalancheController,
+ bgHandler
);
mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
mAutoDismissTime = TEST_AUTO_DISMISS_TIME;
@@ -142,7 +147,8 @@
mUiEventLogger,
mJavaAdapter,
mShadeInteractor,
- mAvalancheController
+ mAvalancheController,
+ mBgHandler
);
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 7cf56aa..abb721a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -84,14 +84,17 @@
* Similar to {@link #startPendingIntentMaybeDismissingKeyguard(PendingIntent, Runnable,
* ActivityTransitionAnimator.Controller)}, but also specifies a fill-in intent and extra
* option that could be used to populate the pending intent and launch the activity. This also
- * allows the caller to avoid dismissing the shade.
+ * allows the caller to avoid dismissing the shade. An optional custom message can be set as
+ * the unlock reason in the alternate bouncer.
*/
void startPendingIntentMaybeDismissingKeyguard(PendingIntent intent,
boolean dismissShade,
@Nullable Runnable intentSentUiThreadCallback,
@Nullable ActivityTransitionAnimator.Controller animationController,
@Nullable Intent fillInIntent,
- @Nullable Bundle extraOptions);
+ @Nullable Bundle extraOptions,
+ @Nullable String customMessage
+ );
/**
* The intent flag can be specified in startActivity().
@@ -134,14 +137,20 @@
void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
boolean afterKeyguardGone);
- /** Authenticates if needed and dismisses keyguard to execute an action. */
+ /**
+ * Authenticates if needed and dismisses keyguard to execute an action.
+ *
+ * TODO(b/348431835) Display the custom message in the new alternate bouncer, when the
+ * device_entry_udfps_refactor flag is enabled.
+ */
void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
boolean afterKeyguardGone, @Nullable String customMessage);
/** Starts an activity and dismisses keyguard. */
void startActivityDismissingKeyguard(Intent intent,
boolean onlyProvisioned,
- boolean dismissShade);
+ boolean dismissShade,
+ @Nullable String customMessage);
/** Starts an activity and dismisses keyguard. */
void startActivityDismissingKeyguard(Intent intent,
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 186bd7c..ba0d7de 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -175,4 +175,6 @@
<dimen name="sfps_progress_bar_padding_from_edge">7dp</dimen>
<dimen name="keyguard_presentation_width">410dp</dimen>
+
+ <dimen name="appclips_backlinks_icon_size">24dp</dimen>
</resources>
diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml
index 30121cc..40f8d0d 100644
--- a/packages/SystemUI/res-product/values-fa/strings.xml
+++ b/packages/SystemUI/res-product/values-fa/strings.xml
@@ -43,18 +43,18 @@
<string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"تلفن بهعلت گرم شدن خاموش شد"</string>
<string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"دستگاه بهعلت گرم شدن خاموش شد"</string>
<string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"رایانه لوحی بهعلت گرم شدن خاموش شد"</string>
- <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"اکنون عملکرد تلفنتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
- <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"اکنون عملکرد دستگاهتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
- <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"اکنون عملکرد رایانه لوحیتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+ <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"اکنون عملکرد تلفنتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر تکضرب بزنید"</string>
+ <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"اکنون عملکرد دستگاهتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر تکضرب بزنید"</string>
+ <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"اکنون عملکرد رایانه لوحیتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر تکضرب بزنید"</string>
<string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"تلفنتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون تلفنتان عملکرد معمولش را دارد.\n\nتلفنتان ممکن است خیلی گرم شود، اگر:\n • از برنامههای نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامههای ناوبری) استفاده کنید\n • فایلهای بزرگ بارگیری یا بارگذاری کنید\n • در دماهای بالا از تلفنتان استفاده کنید"</string>
<string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"دستگاهتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون دستگاهتان عملکرد معمولش را دارد.\n\nدستگاهتان ممکن است خیلی گرم شود، اگر:\n • از برنامههای نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامههای ناوبری) استفاده کنید\n • فایلهای بزرگ بارگیری یا بارگذاری کنید\n • در دماهای بالا از دستگاهتان استفاده کنید"</string>
<string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"رایانه لوحیتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون رایانه لوحیتان عملکرد معمولش را دارد.\n\nرایانه لوحیتان ممکن است خیلی گرم شود، اگر:\n • از برنامههای نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامههای ناوبری) استفاده کنید\n • فایلهای بزرگ بارگیری یا بارگذاری کنید\n • در دماهای بالا از رایانه لوحیتان استفاده کنید"</string>
<string name="high_temp_title" product="default" msgid="5365000411304924115">"تلفن درحال گرم شدن است"</string>
<string name="high_temp_title" product="device" msgid="6622009907401563664">"دستگاه درحال گرم شدن است"</string>
<string name="high_temp_title" product="tablet" msgid="9039733706606446616">"رایانه لوحی درحال گرم شدن است"</string>
- <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"وقتی تلفن درحال خنک شدن است، بعضیاز ویژگیها محدود میشوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
- <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"وقتی دستگاه درحال خنک شدن است، بعضیاز ویژگیها محدود میشوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
- <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"وقتی رایانه لوحی درحال خنک شدن است، بعضیاز ویژگیها محدود میشوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+ <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"وقتی تلفن درحال خنک شدن است، بعضیاز ویژگیها محدود میشوند.\nبرای اطلاعات بیشتر تکضرب بزنید"</string>
+ <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"وقتی دستگاه درحال خنک شدن است، بعضیاز ویژگیها محدود میشوند.\nبرای اطلاعات بیشتر تکضرب بزنید"</string>
+ <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"وقتی رایانه لوحی درحال خنک شدن است، بعضیاز ویژگیها محدود میشوند.\nبرای اطلاعات بیشتر تکضرب بزنید"</string>
<string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"تلفنتان بهطور خودکار سعی میکند خنک شود. همچنان میتوانید از تلفنتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی تلفن خنک شد، عملکرد عادیاش از سرگرفته میشود."</string>
<string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"دستگاهتان بهطور خودکار سعی میکند خنک شود. همچنان میتوانید از دستگاهتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی دستگاه خنک شد، عملکرد عادیاش از سرگرفته میشود."</string>
<string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"رایانه لوحیتان بهطور خودکار سعی میکند خنک شود. همچنان میتوانید از رایانه لوحیتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی رایانه لوحی خنک شد، عملکرد عادیاش از سرگرفته میشود."</string>
diff --git a/packages/SystemUI/res/color/connected_network_primary_color.xml b/packages/SystemUI/res/color/connected_network_primary_color.xml
new file mode 100644
index 0000000..f173c8d
--- /dev/null
+++ b/packages/SystemUI/res/color/connected_network_primary_color.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <item android:color="?androidprv:attr/materialColorOnPrimaryContainer" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/backlinks_rounded_rectangle.xml b/packages/SystemUI/res/drawable/backlinks_rounded_rectangle.xml
new file mode 100644
index 0000000..225f7bd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/backlinks_rounded_rectangle.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetBottom="4dp"
+ android:insetTop="4dp">
+ <shape android:shape="rectangle">
+ <corners android:radius="8dp" />
+ <solid android:color="@android:color/system_surface_container_highest_light" />
+ </shape>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_widgets.xml b/packages/SystemUI/res/drawable/ic_widgets.xml
deleted file mode 100644
index b21d047..0000000
--- a/packages/SystemUI/res/drawable/ic_widgets.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
- ~ Copyright (C) 2024 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.
- -->
-
-<!-- go/gm2-icons, from gs_widgets_vd_theme_24.xml -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:tint="?attr/colorControlNormal"
- android:viewportHeight="960"
- android:viewportWidth="960">
- <path
- android:fillColor="@android:color/black"
- android:pathData="M666,520L440,294L666,68L892,294L666,520ZM120,440L120,120L440,120L440,440L120,440ZM520,840L520,520L840,520L840,840L520,840ZM120,840L120,520L440,520L440,840L120,840ZM200,360L360,360L360,200L200,200L200,360ZM667,408L780,295L667,182L554,295L667,408ZM600,760L760,760L760,600L600,600L600,760ZM200,760L360,760L360,600L200,600L200,760ZM360,360L360,360L360,360L360,360L360,360ZM554,295L554,295L554,295L554,295L554,295ZM360,600L360,600L360,600L360,600L360,600ZM600,600L600,600L600,600L600,600L600,600Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
index 250188b..fab2d8d 100644
--- a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
@@ -16,10 +16,11 @@
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:color="?android:attr/colorControlHighlight">
<item>
<shape android:shape="rectangle">
- <solid android:color="@color/settingslib_state_on_color"/>
+ <solid android:color="?androidprv:attr/materialColorPrimaryContainer"/>
<corners android:radius="@dimen/settingslib_switch_bar_radius"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
index 5566ea3..e316a93 100644
--- a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
@@ -15,7 +15,8 @@
limitations under the License.
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item
android:top="@dimen/settingslib_switch_thumb_margin"
android:bottom="@dimen/settingslib_switch_thumb_margin">
@@ -23,7 +24,7 @@
<size
android:height="@dimen/settingslib_switch_thumb_size"
android:width="@dimen/settingslib_switch_thumb_size"/>
- <solid android:color="@color/settingslib_state_on_color"/>
+ <solid android:color="?androidprv:attr/materialColorOnPrimary"/>
</shape>
</item>
</layer-list>
diff --git a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
index 1d9dacd..e2e6468 100644
--- a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
+++ b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
@@ -16,11 +16,12 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle"
android:width="@dimen/settingslib_switch_track_width"
android:height="@dimen/settingslib_switch_track_height">
<padding android:left="@dimen/settingslib_switch_thumb_margin"
android:right="@dimen/settingslib_switch_thumb_margin"/>
- <solid android:color="@color/settingslib_track_on_color"/>
+ <solid android:color="?androidprv:attr/materialColorPrimary"/>
<corners android:radius="@dimen/settingslib_switch_track_radius"/>
</shape>
diff --git a/packages/SystemUI/res/layout/alert_dialog_systemui.xml b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
index fd06238..14751ef 100644
--- a/packages/SystemUI/res/layout/alert_dialog_systemui.xml
+++ b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
@@ -31,7 +31,6 @@
android:id="@*android:id/contentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="48dp"
android:paddingStart="@dimen/dialog_side_padding"
android:paddingEnd="@dimen/dialog_side_padding"
>
diff --git a/packages/SystemUI/res/layout/app_clips_screenshot.xml b/packages/SystemUI/res/layout/app_clips_screenshot.xml
index a3af9490..6d4e410 100644
--- a/packages/SystemUI/res/layout/app_clips_screenshot.xml
+++ b/packages/SystemUI/res/layout/app_clips_screenshot.xml
@@ -51,13 +51,30 @@
app:layout_constraintStart_toEndOf="@id/save"
app:layout_constraintTop_toTopOf="parent" />
+ <CheckBox
+ android:id="@+id/backlinks_include_data"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_marginStart="16dp"
+ android:checked="true"
+ android:text="@string/backlinks_include_link"
+ android:visibility="gone"
+ app:layout_constraintBottom_toTopOf="@id/preview"
+ app:layout_constraintStart_toEndOf="@id/cancel"
+ app:layout_constraintTop_toTopOf="parent" />
+
<TextView
android:id="@+id/backlinks_data"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
+ android:layout_height="48dp"
+ android:layout_marginStart="16dp"
+ android:background="@drawable/backlinks_rounded_rectangle"
+ android:drawablePadding="4dp"
+ android:gravity="center"
+ android:paddingHorizontal="8dp"
android:visibility="gone"
- app:layout_constraintStart_toEndOf="@id/cancel"
+ app:layout_constraintBottom_toTopOf="@id/preview"
+ app:layout_constraintStart_toEndOf="@id/backlinks_include_data"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 046aecd..acefaae 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/back"
diff --git a/packages/SystemUI/res/layout/contextual.xml b/packages/SystemUI/res/layout/contextual.xml
index 2cd7926..ac840d8 100644
--- a/packages/SystemUI/res/layout/contextual.xml
+++ b/packages/SystemUI/res/layout/contextual.xml
@@ -24,7 +24,7 @@
android:clipChildren="false"
android:clipToPadding="false"
>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/menu"
android:layout_height="match_parent"
android:layout_width="match_parent"
@@ -47,7 +47,7 @@
android:layout_height="match_parent"
android:visibility="invisible"
/>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/accessibility_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/custom_key.xml b/packages/SystemUI/res/layout/custom_key.xml
index dc65777..0b0f4fa 100644
--- a/packages/SystemUI/res/layout/custom_key.xml
+++ b/packages/SystemUI/res/layout/custom_key.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/navigation_side_padding"
diff --git a/packages/SystemUI/res/layout/dream_overlay_open_hub_chip.xml b/packages/SystemUI/res/layout/dream_overlay_open_hub_chip.xml
deleted file mode 100644
index be063a9..0000000
--- a/packages/SystemUI/res/layout/dream_overlay_open_hub_chip.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2024 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.
--->
-<com.android.systemui.animation.view.LaunchableImageView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="@dimen/dream_overlay_bottom_affordance_height"
- android:layout_width="@dimen/dream_overlay_bottom_affordance_width"
- android:layout_gravity="bottom|start"
- android:padding="@dimen/dream_overlay_bottom_affordance_padding"
- android:scaleType="fitCenter"
- android:tint="?android:attr/textColorPrimary"
- android:src="@drawable/ic_widgets"
- android:contentDescription="@string/accessibility_action_open_communal_hub" />
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 84eed6a..227e390 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/home"
diff --git a/packages/SystemUI/res/layout/ime_switcher.xml b/packages/SystemUI/res/layout/ime_switcher.xml
index a2c8308..fa9a12b 100644
--- a/packages/SystemUI/res/layout/ime_switcher.xml
+++ b/packages/SystemUI/res/layout/ime_switcher.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ime_switcher"
android:layout_width="@dimen/navigation_key_width"
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 0bb622b..443e4e3 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -25,7 +25,7 @@
are placed inside a view that has a size controlled by weight. Ensure weight is large enough to
support icon size. Use layout_width=navigation_side_padding like other navbar buttons. -->
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -43,7 +43,7 @@
android:paddingStart="0dp"
android:paddingEnd="0dp"
/>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/rotate_suggestion"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -51,7 +51,7 @@
android:scaleType="centerInside"
android:contentDescription="@string/accessibility_rotate_button"
/>
- <com.android.systemui.navigationbar.buttons.KeyButtonView
+ <com.android.systemui.navigationbar.views.buttons.KeyButtonView
android:id="@+id/accessibility_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 5f59e78..a868ec4 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -17,7 +17,7 @@
*/
-->
-<com.android.systemui.navigationbar.NavigationBarView
+<com.android.systemui.navigationbar.views.NavigationBarView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/navigation_bar_view"
android:layout_height="match_parent"
@@ -26,11 +26,11 @@
android:clipToPadding="false"
android:background="@drawable/system_bar_background">
- <com.android.systemui.navigationbar.NavigationBarInflaterView
+ <com.android.systemui.navigationbar.views.NavigationBarInflaterView
android:id="@+id/navigation_inflater"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false" />
-</com.android.systemui.navigationbar.NavigationBarView>
+</com.android.systemui.navigationbar.views.NavigationBarView>
diff --git a/packages/SystemUI/res/layout/navigation_bar_window.xml b/packages/SystemUI/res/layout/navigation_bar_window.xml
index b2473cd..9442124 100644
--- a/packages/SystemUI/res/layout/navigation_bar_window.xml
+++ b/packages/SystemUI/res/layout/navigation_bar_window.xml
@@ -16,7 +16,7 @@
** limitations under the License.
*/
-->
-<com.android.systemui.navigationbar.NavigationBarFrame
+<com.android.systemui.navigationbar.views.NavigationBarFrame
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_bar_frame"
@@ -24,4 +24,4 @@
android:layout_height="match_parent"
android:layout_width="match_parent">
-</com.android.systemui.navigationbar.NavigationBarFrame>
+</com.android.systemui.navigationbar.views.NavigationBarFrame>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 46f238c..5c6c9a4 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -27,7 +27,7 @@
android:clipToPadding="false"
android:id="@+id/horizontal">
- <com.android.systemui.navigationbar.buttons.NearestTouchFrame
+ <com.android.systemui.navigationbar.views.buttons.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -53,6 +53,6 @@
android:clipToPadding="false"
android:clipChildren="false" />
- </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
+ </com.android.systemui.navigationbar.views.buttons.NearestTouchFrame>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/navigation_layout_vertical.xml b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
index 42e9324..c64e3f7 100644
--- a/packages/SystemUI/res/layout/navigation_layout_vertical.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
@@ -25,7 +25,7 @@
android:paddingBottom="@dimen/nav_content_padding"
android:id="@+id/vertical">
- <com.android.systemui.navigationbar.buttons.NearestTouchFrame
+ <com.android.systemui.navigationbar.views.buttons.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -33,7 +33,7 @@
android:clipToPadding="false"
systemui:isVertical="true">
- <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
+ <com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout
android:id="@+id/ends_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -41,7 +41,7 @@
android:clipToPadding="false"
android:clipChildren="false" />
- <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
+ <com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout
android:id="@+id/center_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -50,6 +50,6 @@
android:clipToPadding="false"
android:clipChildren="false" />
- </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
+ </com.android.systemui.navigationbar.views.buttons.NearestTouchFrame>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/ongoing_activity_chip.xml b/packages/SystemUI/res/layout/ongoing_activity_chip.xml
index beb16b3..154397d 100644
--- a/packages/SystemUI/res/layout/ongoing_activity_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_activity_chip.xml
@@ -34,13 +34,13 @@
android:background="@drawable/ongoing_activity_chip_bg"
android:paddingStart="@dimen/ongoing_activity_chip_side_padding"
android:paddingEnd="@dimen/ongoing_activity_chip_side_padding"
- android:contentDescription="@string/ongoing_phone_call_content_description"
android:minWidth="@dimen/min_clickable_item_size"
>
<ImageView
android:src="@*android:drawable/ic_phone"
android:id="@+id/ongoing_activity_chip_icon"
+ android:contentDescription="@string/ongoing_phone_call_content_description"
android:layout_width="@dimen/ongoing_activity_chip_icon_size"
android:layout_height="@dimen/ongoing_activity_chip_icon_size"
android:tint="?android:attr/colorPrimary"
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index e2b1374..767e16c 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/recent_apps"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index fd768d8..f2945e2 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> het hierdie skermskoot bespeur."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en ander oop apps het hierdie skermskoot bespeur."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Voeg by nota"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Skermopnemer"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
@@ -129,24 +131,25 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Jy sal ophou om <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> op te neem"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <!-- no translation found for share_to_app_chip_accessibility_label (4210256229976947065) -->
+ <skip />
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Jy sal ophou om <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> te deel"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <!-- no translation found for cast_to_other_device_chip_accessibility_label (1680650146639059938) -->
+ <skip />
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Jy sal ophou om <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uit te saai"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +198,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontsluit met gesig. Druk om voort te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesig is herken. Druk om voort te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesig is herken. Druk die ontsluitikoon om voort te gaan."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselleer stawing"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opsies"</string>
@@ -309,10 +314,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Kenmerke soos Kitsdeel en Kry My Toestel gebruik Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sal môreoggend aanskakel"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deel oudio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Deel tans oudio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterykrag"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Oudio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kopstuk"</string>
@@ -384,7 +387,7 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Skermopname"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Begin"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Neem kwessie op"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Teken kwessie aan"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Begin"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Stop"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Foutverslag"</string>
@@ -477,6 +480,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Voeg meer legstukke by"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Langdruk om legstukke te pasmaak"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pasmaak legstukke"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-ikoon vir gedeaktiveerde legstuk"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikoon vir ’n legstuk wat geïnstalleer word"</string>
<string name="edit_widget" msgid="9030848101135393954">"Wysig legstuk"</string>
@@ -495,6 +500,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"kies legstuk"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"verwyder legstuk"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plaas gekose legstuk"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aftrekkieslys"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string>
@@ -548,6 +559,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nuwe kennisgewings nie"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Aanpasbare kennisgewings is aan"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Jou toestel verlaag nou die volume en verminder opspringers op die skerm vir tot twee minute wanneer jy baie kennisgewings in ’n kort tydperk ontvang."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Skakel af"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontsluit om ouer kennisgewings te sien"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Hierdie toestel word deur jou ouer bestuur"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Jou organisasie besit hierdie toestel en kan netwerkverkeer monitor"</string>
@@ -1203,8 +1217,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik vir meer inligting"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker nie"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"voer skermslot in"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Raak die vingerafdruksensor. Dis die korter knoppie aan die sykant van die foon"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Vingerafdruksensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"staaf"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"gaan by toestel in"</string>
@@ -1346,7 +1359,15 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Word gebruik deur <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Onlangs gebruik deur <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Stelsel"</string>
+ <!-- no translation found for shortcut_helper_category_system_controls (3153344561395751020) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_category_system_apps (6001757545472556810) -->
+ <skip />
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Verrigting van veelvuldige take"</string>
+ <!-- no translation found for shortcutHelper_category_recent_apps (7918731953612377145) -->
+ <skip />
+ <!-- no translation found for shortcutHelper_category_split_screen (1159669813444812244) -->
+ <skip />
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Invoer"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Appkortpaaie"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
@@ -1363,6 +1384,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gaan terug"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Swiep enige plek op die raakpaneel links of regs met drie vingers om terug te gaan."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Raakpaneel wat drie vingers wat regs en links beweeg wys"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Toestelskerm wat animasie vir teruggebaar wys"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Sleutelbordlig"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Vlak %1$d van %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Huiskontroles"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 9c24d30..cd3dc51 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ይህን ቅጽበታዊ ገፅ ዕይታ ለይቷል።"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> እና ሌሎች ክፍት መተግበሪያዎች ይህን ቅጽበታዊ ገፅ ዕይታ ለይተዋል።"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ወደ ማስታወሻ አክል"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"የማያ መቅረጫ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገፅ ቀረጻን በማሰናዳት ላይ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገፅ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"እርስዎ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> መቅረጽ ያቆማሉ"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ማያ ገፅን በማጋራት ላይ"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"እርስዎ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ማጋራት ያቆማሉ"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ማያ ገፅን Cast በማድረግ ላይ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"እርስዎ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> cast ማድረግ ያቆማሉ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"በመልክ ተከፍቷል። ለመቀጠል ይጫኑ።"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"መልክ ተለይቶ ታውቋል። ለመቀጠል ይጫኑ።"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"መልክ ተለይቶ ታውቋል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"የተረጋገጠ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ማረጋገጥን ሰርዝ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ተጨማሪ አማራጮች"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ተጨማሪ ምግብሮችን ያክሉ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ምግብሮችን ለማበጀት በረጅሙ ይጫኑ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ምግብሮችን አብጅ"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"የመተግበሪያ አዶ ለተሰናከለ ምግብር"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"የምግብር የመተግበሪያ አዶ ሲጫን"</string>
<string name="edit_widget" msgid="9030848101135393954">"ምግብርን አርትዕ"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ምግብር ይምረጡ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ምግብር አስወግድ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"በቦታ የተመረጠ ምግብር"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ወደታች ተጎታች ምናሌ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ምንም አዲስ ማሳወቂያዎች የሉም"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ተለማማጅ ማሳወቂያዎች በርተዋል"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"በአጭር የጊዜ ቆይታ ውስጥ ብዙ ማሳወቂያዎች ሲደርሱዎት መሣሪያዎ አሁን ድምፁን ይቀንሳል እና በማያ ገፁ ላይ ብቅ ባዮችን እስከ ሁለት ደቂቃዎች ይቀንሳል።"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"አጥፋ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"የቆዩ ማሳወቂያዎችን ለማየት ይክፈቱ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው።"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"የእርስዎ ድርጅት የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ለበለጠ መረጃ መታ ያድርጉ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ምንም ማንቂያ አልተቀናበረም"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ማያ ገጽ መቆለፊያ ያስገቡ"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"የጣት አሻራ ዳሳሹን ይንኩ። በስልኩ ጎን በኩል አጠር ያለው አዝራር ነው"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"የጣት አሻራ ዳሳሽ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ያረጋግጡ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"መሣሪያን ያስገቡ"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"በ<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ጥቅም ላይ እየዋለ ነው"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"በቅርብ ጊዜ በ<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ጥቅም ላይ ውሏል"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ሥርዓት"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"የሥርዓት መቆጣጠሪያዎች"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"የሥርዓት መተግበሪያዎች"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ብዙ ተግባራትን በተመሳሳይ ጊዜ ማከናወን"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"የቅርብ ጊዜ መተግበሪያዎች"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"የተከፈለ ማያ ገፅ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ግብዓት"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"የመተግበሪያ አቋራጮች"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ወደኋላ ተመለስ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ወደኋላ ለመመለስ በመዳሰሻ ሰሌዳው ላይ በየትኛውም ቦታ ሦስት ጣቶችን በመጠቀም ወደግራ ወይም ወደቀኝ ያንሸራትቱ።"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ሦስት ጣቶች ወደቀኝ እና ግራ ሲንቀሳቀሱ የሚያሳይ የመዳሰሻ ሰሌዳ"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"የኋላ ምልክት እነማ የሚያሳይ የመሣሪያ ማያ ገፅ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"የቁልፍ ሰሌዳ የጀርባ ብርሃን"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ደረጃ %1$d ከ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"የቤት ውስጥ ቁጥጥሮች"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 8711e78..f894a29 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" لقطة الشاشة هذه."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" والتطبيقات المفتوحة الأخرى لقطة الشاشة هذه."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"إضافة إلى الملاحظة"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"تضمين الرابط"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"مسجّل الشاشة"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"سيتم إيقاف تسجيل محتوى <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"جارِ مشاركة محتوى الشاشة"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"سيتم إيقاف مشاركة محتوى <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"جارٍ بثّ محتوى الشاشة"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"سيتم إيقاف بث محتوى <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح الجهاز بالتعرّف على وجهك. اضغط للمتابعة."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"تم التعرّف على الوجه. اضغط للمتابعة."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"تمّ فتح قفل جهازك باستخدام بصمة الوجه. انقر للمتابعة."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"إلغاء المصادقة"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزيد من الخيارات"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"يُستخدَم البلوتوث في ميزات مثل Quick Share و\"العثور على جهازي\""</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"سيتم تفعيل البلوتوث صباح الغد"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"مشاركة الصوت"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"جارٍ مشاركة الصوت"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"سماعة الرأس"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"إضافة المزيد من التطبيقات المصغّرة"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"اضغط مع الاستمرار لتخصيص التطبيقات المصغّرة."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"تخصيص التطبيقات المصغَّرة"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"رمز التطبيق المصغّر غير المفعّل"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"رمز تطبيق مصغَّر جارٍ تثبيته"</string>
<string name="edit_widget" msgid="9030848101135393954">"تعديل التطبيق المصغَّر"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"اختيار التطبيق المصغّر"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"إزالة التطبيق المصغّر"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"إضافة التطبيق المصغّر المحدَّد"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"القائمة المنسدلة"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ما مِن إشعارات"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ما مِن إشعارات جديدة"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"\"الإشعارات التكيّفية\" مفعَّلة"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"عند تلقّي إشعارات متعددة في فترة زمنية قصيرة، يخفِّض جهازك الصوت ويقلّل من ظهور النوافذ المنبثقة على الشاشة لمدة تصل إلى دقيقتين."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"إيقاف"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"افتَح قفل الشاشة لعرض الإشعارات الأقدم."</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"يتولّى أحد الوالدين إدارة هذا الجهاز."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"تملك مؤسستك هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة."</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"إدخال الرمز لفتح القفل"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"المس أداة استشعار بصمة الإصبع المدمَجة في الزر الأقصر في جانب الهاتف"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"مستشعر بصمات الإصبع"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"المصادقة"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"الدخول إلى الجهاز"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"قيد الاستخدام في <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"تم الاستخدام مؤخرًا في <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"النظام"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"عناصر التحكّم في النظام"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"تطبيقات النظام"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"تعدُّد المهام"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"التطبيقات المستخدمة مؤخرًا"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"تقسيم الشاشة"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"الإدخال"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"اختصارات التطبيقات"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"رجوع"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"للرجوع، مرِّر سريعًا لليسار أو لليمين باستخدام ثلاثة أصابع في أي مكان على لوحة اللمس."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"لوحة لمس تعرض ثلاثة أصابع تتحرك يمينًا ويسارًا"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"شاشة جهاز تعرض صورة متحركة لإيماءة الرجوع"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"الإضاءة الخلفية للوحة المفاتيح"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"مستوى الإضاءة: %1$d من %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"إدارة المنزل آليًّا"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 785f3f4..e8d788b6 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>এ এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> আৰু আন খোলা এপ্সমূহে এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"টোকাত যোগ দিয়ক"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"লিংক অন্তৰ্ভুক্ত কৰক"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীন ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"আপুনি <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ৰেকৰ্ড কৰা বন্ধ কৰিব"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্ৰীন শ্বেয়াৰ কৰি থকা হৈছে"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"আপুনি <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> শ্বেয়াৰ কৰা বন্ধ কৰিব"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"স্ক্ৰীন কাষ্ট কৰি থকা হৈছে"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"আপুনি <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> কাষ্ট কৰা বন্ধ কৰিব"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ বাতিল কৰক"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"অধিক বিকল্প"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"অধিক ৱিজেট যোগ দিয়ক"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ৱিজেট কাষ্টমাইজ কৰিবলৈ দীঘলীয়াকৈ টিপক"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ৱিজেট কাষ্টমাইজ কৰক"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"অক্ষম কৰা ৱিজেটৰ বাবে এপৰ চিহ্ন"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ইনষ্টল কৰি থকা এটা ৱিজেটৰ বাবে এপৰ চিহ্ন"</string>
<string name="edit_widget" msgid="9030848101135393954">"ৱিজেট সম্পাদনা কৰক"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ৱিজেট বাছনি কৰক"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ৱিজেট আঁতৰাওক"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বাছনি কৰা ৱিজেটটো ৰাখক"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুল-ডাউনৰ মেনু"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনো জাননী নাই"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"কোনো নতুন জাননী নাই"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"অভিযোজিত জাননী অন কৰা আছে"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"আপোনাৰ ডিভাইচে এতিয়া ভলিউম কমায়, কম সময়ৰ ভিতৰত বহুতো জাননী পালে ২ মিনিটলৈকে স্ক্ৰীনত ওলোৱা পপ-আপ কমায়।"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"অফ কৰক"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুৰণি জাননী চবলৈ আনলক কৰক"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইচটোৰ গৰাকী আপোনাৰ প্ৰতিষ্ঠান আৰু ই নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"অধিক তথ্যৰ বাবে টিপক"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনো এলাৰ্ম ছেট কৰা হোৱা নাই"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"স্ক্ৰীন লকটো দিয়ক"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক। এইটো হৈছে আপোনাৰ ফ’নটোৰ কাষৰফালে থকা চুটি বুটামটো"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"বিশ্বাসযোগ্যতা প্ৰমাণ কৰক"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইচ আনলক কৰক"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)এ ব্যৱহাৰ কৰি আছে"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"শেহতীয়াকৈ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)এ ব্যৱহাৰ কৰিছে"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ছিষ্টেম"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ছিষ্টেমৰ নিয়ন্ত্ৰণ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ছিষ্টেম এপ্"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"মাল্টিটাস্কিং"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"শেহতীয়া এপ্সমূহ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"বিভাজিত স্ক্ৰীন"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ইনপুট"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"এপ্ শ্বৰ্টকাটসমূহ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"উভতি যাওক"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"উভতি যাবলৈ, টাচ্চপেডৰ যিকোনো স্থানত তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁ বা সোঁফালে ছোৱাইপ কৰক।"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"তিনিটা আঙুলি সোঁ আৰু বাওঁফালে লৰচৰ কৰা দেখুওৱা টাচ্চপেড"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"পিছফালৰ নিৰ্দেশৰ এনিমেশ্বন দেখুওৱা ডিভাইচ স্ক্ৰীন"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীব’ৰ্ডৰ বেকলাইট"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dৰ %1$d স্তৰ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ঘৰৰ সা-সৰঞ্জামৰ নিয়ন্ত্ৰণ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 1c75a9b3..3476f11 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu skrinşotu aşkarladı."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> və digər açıq tətbiqlər bu skrinşotu aşkarladı."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qeydə əlavə edin"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Ekran yazıcısı"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqinin çəkilməsini dayandıracaqsınız"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılır"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqinin paylaşılmasını dayandıracaqsınız"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekran yayımlanır"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqinin yayımlanmasını dayandıracaqsınız"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Üz tanınıb. Davam etmək üçün basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb davam edin."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"İdentifikasiyanı ləğv edin"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Digər seçimlər"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Cəld Paylaşım və Cihazın Tapılması kimi funksiyalar Bluetooth istifadə edir"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sabah səhər aktiv ediləcək"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audio paylaşın"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio paylaşılır"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batareya"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Qulaqlıq"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Vidcetlər əlavə edin"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Basıb saxlayaraq vidcetləri fərdiləşdirin"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidcetləri fərdiləşdirin"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Deaktiv edilmiş vidcet üçün tətbiq ikonası"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Quraşdırılan vidcet üçün tətbiq ikonası"</string>
<string name="edit_widget" msgid="9030848101135393954">"Vidceti redaktə edin"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidcet seçin"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidceti silin"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilmiş vidceti yerləşdirin"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aşağı çəkilən menyu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Heç bir bildiriş yoxdur"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildiriş yoxdur"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptiv bildirişlər aktivdir"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Qısa vaxtda çoxlu bildiriş alanda cihaz səsi azaldır, ekranda popapları iki dəqiqəyə qədər qısaldır."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiv edin"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Köhnə bildirişləri görmək üçün kilidi açın"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz valideyniniz tərəfindən idarə olunur"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Təşkilatınız bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ətraflı məlumat üçün toxunun"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Siqnal ayarlanmayıb"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ekran kilidi daxil edin"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Barmaq izi sensoruna toxunun. Telefonun yan tərəfindəki qısa düymədir"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Barmaq izi sensoru"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"doğrulayın"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz daxil edin"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) istifadə edir"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Bu yaxınlarda <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) istifadə edib"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistem nizamlayıcıları"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistem tətbiqləri"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Çoxsaylı tapşırıq icrası"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Son tətbiqlər"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Bölünmüş ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Daxiletmə"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Tətbiq qısayolları"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri qayıdın"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Geri qayıtmaq üçün taçpedin istənilən yerində üç barmaqla sola və ya sağa çəkin."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Üç barmağın sağa və sola hərəkət etdiyini göstərən taçped"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Geri jesti üçün animasiya göstərən cihaz ekranı"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura işığı"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Səviyyə %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ev nizamlayıcıları"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 6072605..e880a8b 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u belešku"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Snimač ekrana"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavićete snimanje za: <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran se deli"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavićete deljenje za: <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Prebacuje se ekran"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavićete prebacivanje za: <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite potvrdu identiteta"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Još opcija"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugi pritisak za prilagođavanje vidžeta"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi vidžete"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućen vidžet"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za vidžet koji se instalira"</string>
<string name="edit_widget" msgid="9030848101135393954">"Izmeni vidžet"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izaberite vidžet"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklonite vidžet"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavite izabrani vidžet"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obaveštenja"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obaveštenja"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilag. obaveštenja su uključena"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj sada smanjuje zvuk i broj iskačućih prozora na ekranu do 2 minuta kad primite mnogo obaveštenja u kratkom roku."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte za starija obaveštenja"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije podešen"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"unesite otključavanje ekrana"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dodirnite senzor za otisak prsta. To je kraće dugme na bočnoj strani telefona"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"potvrdite identitet"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koriste <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemske kontrole"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Obavljanje više zadataka istovremeno"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podeljeni ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečice za aplikacije"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Da biste se vratili, prevucite ulevo ili udesno sa tri prsta bilo gde na tačpedu."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tačped sa prikazom tri prsta koji se pomeraju udesno i ulevo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran uređaja sa prikazom animacije pokreta za nazad"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvetljenje tastature"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index df1227f..9954246 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Праграма \"<xliff:g id="APPNAME">%1$s</xliff:g>\" выявіла гэты здымак экрана."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> і іншыя адкрытыя праграмы выявілі гэты здымак экрана."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Дадаць у нататку"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Дадаць спасылку"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Запіс экрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Запіс з праграмы <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> будзе спынены"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран абагульваецца"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Абагульванне з праграмы <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> будзе спынена"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Экран трансліруецца"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Трансляцыя праграмы <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> будзе спынена"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблакіравана распазнаваннем твару. Націсніце для працягу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Твар распазнаны. Націсніце для працягу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Твар распазнаны. Націсніце, каб працягнуць."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Распазнана"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасаваць аўтэнтыфікацыю"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Іншыя варыянты"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Дадаць іншыя віджэты"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Доўга націскайце, каб наладзіць віджэты"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Наладзіць віджэты"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок праграмы для адключанага віджэта"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок праграмы для віджэта ў працэсе ўсталявання"</string>
<string name="edit_widget" msgid="9030848101135393954">"Змяніць віджэт"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбраць віджэт"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"выдаліць віджэт"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"размясціць выбраны віджэт"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"высоўнае меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Апавяшчэнняў няма"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Няма новых апавяшчэнняў"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптыўныя апавяшчэнні ўключаны"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Пры атрыманні шматлікіх апавяшчэнняў за кароткі час прылада памяншае гучнасць і колькасць усплывальных вокнаў на 2 хв."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Выключыць"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблакіруйце, каб убачыць усе апавяшчэнні"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Гэта прылада знаходзіцца пад кантролем бацькоў"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша арганізацыя валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Націсніце, каб убачыць больш"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма будзільнікаў"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"прыступіць да разблакіроўкі экрана"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Дакраніцеся да сканера адбіткаў пальцаў. Гэта кароткая кнопка на баку вашага тэлефона"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер адбіткаў пальцаў"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"правесці аўтэнтыфікацыю"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"адкрыць галоўны экран прылады"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Зараз выкарыстоўваецца праграмай \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Нядаўна выкарыстоўваўся праграмай \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Сістэма"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Элементы кіравання сістэмай"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Сістэмныя праграмы"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Шматзадачнасць"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Нядаўнія праграмы"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Падзелены экран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Увод"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ярлыкі праграм"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Каб вярнуцца на папярэдні экран, правядзіце трыма пальцамі ўлева або ўправа ў любым месцы сэнсарнай панэлі."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Паказваецца, як на сэнсарнай панэлі тры пальцы рухаюцца ўправа і ўлева"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"На экране прылады паказваецца анімацыя жэста \"Назад\""</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Падсветка клавіятуры"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Узровень %1$d з %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Кіраванне домам"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index b7c8467..bb5986d 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> установи заснемането на тази екранна снимка."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени приложения установиха заснемането на тази екранна снимка."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавяне към бележката"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Запис на екрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ще спрете да записвате <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екранът се споделя"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ще спрете да споделяте <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Екранът се предава"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ще спрете да предавате <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отключено с лице. Натиснете, за да продължите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето бе разпознато. Натиснете, за да продължите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето бе разпознато. Продължете чрез иконата за отключване."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Удостоверено"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Анулиране на удостоверяването"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Още опции"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функции като „Бързо споделяне“ и „Намиране на устройството ми“ използват Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ще се включи утре сутрин"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Споделяне на звука"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Звукът се споделя"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавете още приспособления"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Натиснете продължително за персонализ. на приспос."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Персонализиране на приспособленията"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона на приложение за деактивирано приспособление"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона на приложение, чието приспособление се инсталира"</string>
<string name="edit_widget" msgid="9030848101135393954">"Редактиране на приспособлението"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"избиране на приспособление"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"премахване на приспособлението"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставяне на избраното приспособление"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падащо меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Стартиране сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Няма известия"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Няма нови известия"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивните известия са вкл."</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"У-вото ви намалява силата на звука и броя на изскачащите прозорци за период до 2 мин, ако получавате много известия за кратко време."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Изключване"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отключете за достъп до по-стари известия"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Това устройство се управлява от родителя ви"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацията ви притежава това устройство и може да наблюдава трафика в мрежата"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Докоснете за още информация"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма зададен будилник"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"въведете опция за заключване на екрана"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Докоснете сензора за отпечатъци. Това е по-късият бутон отстрани на телефона"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отпечатъци"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"удостоверяване"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"вход в устройството"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Използва се от <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Наскоро използвано от <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Системни"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системни контроли"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системни приложения"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Изпълняване на няколко задачи едновременно"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Скорошни приложения"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделен екран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Въвеждане"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Преки пътища към приложения"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"За да се върнете назад, прекарайте три пръста наляво или надясно по сензорния панел."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Сензорен панел, върху който три пръста се движат надясно и наляво"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екран на устройство, показващ анимация за жеста за връщане назад"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка на клавиатурата"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d от %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за дома"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 9fa4c6e..716fee2 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, এই স্ক্রিনশট শনাক্ত করেছে।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> এবং খোলা থাকা অন্য অ্যাপ এই স্ক্রিনশট শনাক্ত করেছে।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"নোটে যোগ করুন"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"স্ক্রিন রেকর্ডার"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"এটির জন্য <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অ্যাপের কন্টেন্ট রেকর্ড হওয়া বন্ধ হয়ে যাবে"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্রিন শেয়ার করা হচ্ছে"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"এটির জন্য <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অ্যাপের কন্টেন্ট শেয়ার করা বন্ধ হয়ে যাবে"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"স্ক্রিন কাস্ট করা হচ্ছে"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"এটির জন্য <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অ্যাপের কন্টেন্ট কাস্ট হওয়া বন্ধ হয়ে যাবে"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে আনলক আইকন প্রেস করুন।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"যাচাইকরণ বাতিল করুন"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"আরও বিকল্প"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"দ্রুত শেয়ার ও Find My Device-এর মতো ফিচার ব্লুটুথ ব্যবহার করে"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ব্লুটুথ আগামীকাল সকালে চালু হয়ে যাবে"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"অডিও শেয়ার করুন"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"অডিও শেয়ার করা হচ্ছে"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"অডিও"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"হেডসেট"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"আরও উইজেট যোগ করুন"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"উইজেট কাস্টমাইজ করতে বেশিক্ষণ প্রেস করুন"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"উইজেট কাস্টমাইজ করুন"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"বন্ধ করা উইজেটের জন্য অ্যাপের আইকন"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ইনস্টল করা হচ্ছে এমন উইজেটের অ্যাপ আইকন"</string>
<string name="edit_widget" msgid="9030848101135393954">"উইজেট এডিট করুন"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"উইজেট বেছে নিন"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"উইজেট সরান"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বেছে নেওয়া উইজেটটি রাখুন"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুলডাউন মেনু"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনও বিজ্ঞপ্তি নেই"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"নতুন কোনও বিজ্ঞপ্তি নেই"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"অ্যাডাপ্টিভ বিজ্ঞপ্তি চালু আছে"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"অল্প সময়ে অনেক বেশি বিজ্ঞপ্তি পেলে, আপনার ডিভাইস এখন ২ মিনিটের জন্য ভলিউম ও স্ক্রিনে আসা পপ-আপ কমায়।"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"বন্ধ করুন"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুরনো বিজ্ঞপ্তি দেখতে আনলক করুন"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের এবং এরা ডিভাইসের নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনও অ্যালার্ম সেট করা নেই"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"স্ক্রিন লক খুলুন"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ফিঙ্গারপ্রিন্ট সেন্সর টাচ করুন। এটি ফোনের পাশের দিকে থাকা তুলনামূলক ছোট বোতাম"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ফিঙ্গারপ্রিন্ট সেন্সর"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"যাচাই করিয়ে নিন"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইস আনলক করুন"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ব্যবহার করা হচ্ছে"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"সম্প্রতি <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ব্যবহার করা হয়েছে"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"সিস্টেম"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"সিস্টেম কন্ট্রোল"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"সিস্টেম অ্যাপ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"মাল্টিটাস্কিং"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"সম্প্রতি ব্যবহার করা অ্যাপ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"স্প্লিট স্ক্রিন"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ইনপুট"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"অ্যাপ শর্টকাট"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ফিরে যান"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ফিরে যেতে, টাচপ্যাডের যেকোনও জায়গায় তিনটি আঙুল দিয়ে ডান বা বাঁদিকে সোয়াইপ করুন।"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"টাচপ্যাডে, তিনটি আঙুল ডান ও বাঁদিকে সরানো দেখানো হচ্ছে"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ডিভাইসের স্ক্রিনে ফিরে যাওয়ার জেসচারের অ্যানিমেশন দেখানো হচ্ছে"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীবোর্ড ব্যাকলাইট"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-এর মধ্যে %1$d লেভেল"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"হোম কন্ট্রোল"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 8dee87a..5ab4faa 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u bilješku"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Snimač ekrana"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavit ćete snimanje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje ekrana"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavit ćete dijeljenje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Emitiranje ekrana"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavit ćete emitiranje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano licem. Pritisnite da nastavite."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice prepoznato. Pritisnite da nastavite."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu za otklj. da nastavite."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite autentifikaciju"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
@@ -310,7 +313,7 @@
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije kao što su Quick Share i Pronađi moj uređaj koriste Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth će se uključiti sutra ujutro"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Dijeli zvuk"</string>
- <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Zajedničko slušanje"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Dijeljenje zvuka"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string>
@@ -382,7 +385,7 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Snimanje ekrana"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Započnite"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavite"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Snimite problem"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Zabilježite problem"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Pokrenite"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Zaustavite"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Izvještaj o grešci"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pritisnite i zadržite da prilagodite vidžete"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodite vidžete"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni vidžet"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za vidžet koji se instalira"</string>
<string name="edit_widget" msgid="9030848101135393954">"Uredite vidžet"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odabir vidžeta"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklanjanje vidžeta"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavljanje odabranog vidžeta"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavještenja"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljiva obavještenja su uključena"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj smanjuje jačinu zvuka i broj skočnih prozora na ekranu do dvije minute kada dobijate mnogo obavještenja unutar kratkog vremenskog raspona."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obavještenja"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je vlasnik ovog uređaja i može nadzirati mrežni saobraćaj"</string>
@@ -784,7 +798,7 @@
<string name="keyboard_shortcut_join" msgid="3578314570034512676">"ili"</string>
<string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Brisanje upita za pretraživanje"</string>
<string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"Prečice na tastaturi"</string>
- <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pretraživanje prečica"</string>
+ <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pretražite prečice"</string>
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nisu pronađene prečice"</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Sistem"</string>
<string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Unos"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"unos zaključavanja ekrana"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dodirnite senzor za otisak prsta. To je kraće dugme na bočnoj strani telefona"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificiranje"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pristup uređaju"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno je koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemske kontrole"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podijeljeni ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečice aplikacije"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Da se vratite, prevucite ulijevo ili udesno s tri prsta bilo gdje na dodirnoj podlozi."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Dodirna podloga prikazuje tri prsta koji se pomjeraju desno-lijevo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran uređaja pokazuje animaciju pokreta unazad"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tastature"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index f9d343f..052b1e8 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectat aquesta captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i altres aplicacions obertes han detectat aquesta captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Afegeix a una nota"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Gravació de pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Deixaràs de gravar <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"S\'està compartint la pantalla"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Deixaràs de compartir <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"S\'està emetent la pantalla"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Deixaràs d\'emetre <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S\'ha desbloquejat amb la cara. Prem per continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"S\'ha reconegut la cara. Prem per continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"S\'ha reconegut la cara. Prem la icona per continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel·la l\'autenticació"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Més opcions"</string>
@@ -386,7 +389,7 @@
<string name="qs_record_issue_start" msgid="2979831312582567056">"Inicia"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Atura"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Informe d\'errors"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"L\'experiència amb el dispositiu s\'ha vist afectada?"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Quina part de l\'experiència s\'ha vist afectada?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Selecciona el tipus de problema"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Gravació de pantalla"</string>
<string name="performance" msgid="6552785217174378320">"Rendiment"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Afegeix més widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén premut per personalitzar els widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalitza els widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona de l\'aplicació per a widget desactivat"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona de l\'aplicació d\'un widget que s\'està instal·lant"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edita el widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecciona el widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"suprimeix el widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"col·loca el widget seleccionat"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hi ha cap notificació nova"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notif. adaptatives activades"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"El dispositiu abaixa el volum i redueix les notificacions emergents durant un màxim de 2 minuts quan reps moltes notificacions en poc temps."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueja per veure notif. anteriors"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Els teus pares gestionen aquest dispositiu"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"La teva organització és propietària del dispositiu i és possible que supervisi el trànsit de xarxa"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca per obtenir més informació"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Cap alarma definida"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"utilitza el bloqueig de pantalla"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca el sensor d\'empremtes digitals. És el botó més curt del lateral del telèfon."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor d\'empremtes digitals"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accedir al dispositiu"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En ús per <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Utilitzat recentment per <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controls del sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicacions del sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasca"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicacions recents"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Dreceres d\'aplicacions"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Torna"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Per tornar enrere, llisca cap a l\'esquerra o cap a la dreta amb tres dits en qualsevol lloc del ratolí tàctil."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Ratolí tàctil que mostra tres dits que es mouen cap a la dreta i cap a l\'esquerra"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla del dispositiu que mostra l\'animació del gest per anar enrere"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroil·luminació del teclat"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivell %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controls de la llar"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 3caa23d..55af3cc 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -103,11 +103,13 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikace <xliff:g id="APPNAME">%1$s</xliff:g> objevila tento snímek obrazovky."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ostatní otevřené aplikace objevily tento snímek obrazovky."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Přidat do poznámky"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Nahrávání obrazovky"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Začít nahrávat?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Během nahrávání má Android přístup k veškerému obsahu, který je viditelný na obrazovce nebo se přehrává v zařízení. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Během nahrávání má Android přístup k veškerému obsahu, který je viditelný na obrazovce nebo se přehrává v zařízení. Dejte proto pozor na hesla, platební údaje, zprávy, fotografie, zvukové záznamy nebo videa."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Během nahrávání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s informacemi, jako jsou hesla, platební údaje, zprávy, fotky, zvukové záznamy nebo videa."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Začít nahrávat"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Nahrávat zvuk"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Přestane se nahrávat aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sdílení obrazovky"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Přestane se sdílet aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Odesílání obsahu obrazovky"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Přestane se odesílat aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odemknuto obličejem. Pokračujte stisknutím."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obličej rozpoznán. Pokračujte stisknutím."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušit ověření"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Další možnosti"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth využívají funkce jako Quick Share a Najdi moje zařízení."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se zapne zítra ráno."</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sdílet zvuk"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Zvuk se sdílí"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Sluchátka"</string>
@@ -389,7 +390,7 @@
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Ukončit"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Zpráva o chybě"</string>
<string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Co v zařízení bylo ovlivněno?"</string>
- <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Vyberte druh problém"</string>
+ <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Vyberte druh problému"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Záznam obrazovky"</string>
<string name="performance" msgid="6552785217174378320">"Výkon"</string>
<string name="user_interface" msgid="3712869377953950887">"Uživatelské rozhraní"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Přidat další widgety"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dlouhým stisknutím můžete přizpůsobit widgety"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Přizpůsobit widgety"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikace s deaktivovaným widgetem"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikace při probíhající instalaci widgetu"</string>
<string name="edit_widget" msgid="9030848101135393954">"Upravit widget"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrat widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranit widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umístit vybraný widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbalovací nabídka"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Žádná nová oznámení"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Jsou zapnutá adaptivní oznámení"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Když během krátké chvíle obdržíte mnoho oznámení, zařízení teď až na dvě minuty sníží hlasitost a omezí na obrazovce vyskakovací okna."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnout"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Starší oznámení se zobrazí po odemknutí"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zařízení spravuje rodič"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Toto zařízení vlastní vaše organizace, která může sledovat síťový provoz"</string>
@@ -624,11 +636,11 @@
<string name="screen_pinning_negative" msgid="6882816864569211666">"Ne, děkuji"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"Aplikace byla připnuta"</string>
<string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikace byla odepnuta"</string>
- <string name="stream_voice_call" msgid="7468348170702375660">"Hovor"</string>
+ <string name="stream_voice_call" msgid="7468348170702375660">"Hovory"</string>
<string name="stream_system" msgid="7663148785370565134">"Systém"</string>
<string name="stream_ring" msgid="7550670036738697526">"Vyzvánění"</string>
<string name="stream_music" msgid="2188224742361847580">"Média"</string>
- <string name="stream_alarm" msgid="16058075093011694">"Budík"</string>
+ <string name="stream_alarm" msgid="16058075093011694">"Budíky"</string>
<string name="stream_notification" msgid="7930294049046243939">"Oznámení"</string>
<string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
<string name="stream_dtmf" msgid="7322536356554673067">"Tónová volba"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím zobrazíte další informace"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Budík nenastaven"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"zadejte zámek obrazovky"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotkněte se snímače otisků prstů. Vypínač je kratší tlačítko na boku telefonu."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Snímač otisků prstů"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ověříte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"zadáte zařízení"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Právě používán aplikací <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedávno použila aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Systém"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Ovládací prvky systému"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systémové aplikace"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Poslední aplikace"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Rozdělená obrazovka"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vstup"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Zkratky aplikací"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zpět"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pokud se chcete vrátit zpět, stačí kdekoli na touchpadu přejet třemi prsty doleva nebo doprava."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad se třemi prsty, které se pohybují doprava a doleva"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Obrazovka zařízení s animaci gesta k vrácení zpět"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvícení klávesnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Úroveň %1$d z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládání domácnosti"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 5333768..3876827 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registreret dette screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åbne apps har registreret dette screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Føj til note"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Skærmoptagelse"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du stopper optagelse af <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skærmen deles"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du stopper deling af <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Skærmen castes"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du stopper casting af <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansigt genkendt. Tryk for at fortsætte."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansigt genkendt. Tryk på oplåsningsikonet for at fortsætte."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuller godkendelsen"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere valgmuligheder"</string>
@@ -382,7 +385,7 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Skærmoptagelse"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Optag problem"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Registrer problem"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Start"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Stop"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Fejlrapport"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tilføj flere widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Hold fingeren nede for at tilpasse widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpas widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktiveret widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikonet for en widget er ved at blive installeret"</string>
<string name="edit_widget" msgid="9030848101135393954">"Rediger widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vælg widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer valgt widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullemenu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye notifikationer"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifikationer er aktiveret"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Din enhed skruer nu ned for lydstyrken og reducerer pop op-vinduer på skærmen i op til to minutter, når du modtager mange notifikationer over kort tid."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås op for at se ældre notifikationer"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enhed administreres af din forælder"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryk for at få flere oplysninger"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm er indstillet"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"angiv skærmlås"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Sæt fingeren på fingeraftrykssensoren. Det er den mindste knap på siden af telefonen"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeraftrykssensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"godkende"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"få adgang til enheden"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Bruges af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Brugt for nylig af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemstyring"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemapps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Seneste apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Opdelt skærm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Appgenveje"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbage"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Du kan gå tilbage ved at stryge mod venstre eller højre med tre fingre et vilkårligt sted på touchpladen."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchplade viser tre fingre, der bevæger sig til højre og venstre"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Enhedsskærm, der viser en animation, som demonstrerer, hvordan man går tilbage"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturets baggrundslys"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d af %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemmestyring"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 847e25f..b2e0ca8 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> hat diesen Screenshot erkannt."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> und andere geöffnete Apps haben diesen Screenshot erkannt."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Zu Notiz hinzufügen"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Bildschirmaufzeichnung"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wird dann nicht mehr aufgezeichnet"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bildschirm wird geteilt"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wird dann nicht mehr geteilt"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Bildschirm wird übertragen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wird dann nicht mehr übertragen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Gerät mit dem Gesicht entsperrt. Tippe, um fortzufahren."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesicht erkannt. Tippe, um fortzufahren."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesicht erkannt. Tippe zum Fortfahren auf das Symbol „Entsperren“."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Authentifizierung abbrechen"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Weitere Optionen"</string>
@@ -383,10 +386,10 @@
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starten"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Beenden"</string>
<string name="qs_record_issue_label" msgid="8166290137285529059">"Problem aufnehmen"</string>
- <string name="qs_record_issue_start" msgid="2979831312582567056">"Aufnahme starten"</string>
+ <string name="qs_record_issue_start" msgid="2979831312582567056">"Starten"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Aufnahme beenden"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Fehlerbericht"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Welche Bereiche des Geräts waren betroffen?"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Welche Probleme sind bei deinem Gerät aufgetreten?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Art des Problems auswählen"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Bildschirmaufnahme"</string>
<string name="performance" msgid="6552785217174378320">"Leistung"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weitere Widgets hinzufügen"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Lange drücken, um Widgets anzupassen"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets anpassen"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-Symbol für deaktiviertes Widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App-Symbol für ein Widget, das gerade installiert wird"</string>
<string name="edit_widget" msgid="9030848101135393954">"Widget bearbeiten"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Widget auswählen"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"Widget entfernen"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ausgewähltes Widget in den Bearbeitungsmodus versetzen"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Pull-down-Menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Keine neuen Benachrichtigungen"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive Benachrichtigungen an"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Wenn du in kurzer Zeit viele Benachrichtigungen erhältst, reduziert dein Gerät jetzt die Lautstärke und Pop-ups bis zu 2 Minuten lang."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktivieren"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Für ältere Benachrichtigungen entsperren"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dieses Gerät wird von deinen Eltern verwaltet"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Für weitere Informationen tippen"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Kein Wecker gestellt"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"Displaysperre eingeben"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Berühre den Fingerabdrucksensor. Das ist die kürzere Taste an der Seite des Smartphones."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerabdrucksensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authentifizieren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"Eingeben des Geräts"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Verwendet von <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kürzlich von <xliff:g id="APP_NAME">%1$s</xliff:g> verwendet (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemsteuerelemente"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System-Apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Zuletzt aktive Apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Splitscreen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Eingabe"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-Verknüpfungen"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zurück"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Wenn du zurückgehen möchtest, wische an einer beliebigen Stelle des Touchpads mit drei Fingern nach links oder rechts."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mit drei Fingern, die sich nach links und rechts bewegen"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Bildschirm zeigt eine Animation der Touch-Geste „Zurück“"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturbeleuchtung"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d von %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Smart-Home-Steuerung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 80fe3d2..766956f 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> εντόπισε αυτό το στιγμιότυπο οθόνης."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> και άλλες ανοικτές εφαρμογές εντόπισαν το στιγμιότυπο οθόνης."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Προσθήκη σε σημείωση"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Εγγραφή οθόνης"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Επεξεργασία εγγραφής οθόνης"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Θα διακόψετε την εγγραφή της εφαρμογής <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Γίνεται κοινοποίηση οθόνης"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Θα διακόψετε την κοινή χρήση της εφαρμογής <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Μετάδοση οθόνης"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Θα διακόψετε τη μετάδοση της εφαρμογής <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για συνέχεια."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Το πρόσωπο αναγνωρ. Πατήστε το εικον. ξεκλειδ. για συνέχεια."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ακύρωση ελέγχου ταυτότητας"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Περισσότερες επιλογές"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Λειτουργίες όπως το Quick Share και η Εύρεση συσκευής χρησιμοποιούν το Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Το Bluetooth θα ενεργοποιηθεί αύριο το πρωί"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Κοινή χρήση ήχου"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Κοινή χρήση ήχου σε εξέλιξη"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ήχος"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ακουστικά"</string>
@@ -396,7 +397,7 @@
<string name="thermal" msgid="6758074791325414831">"Θερμικό"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Λειτουργία ενός χεριού"</string>
<string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Συσκευές ακοής"</string>
- <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Ενεργά"</string>
+ <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Ενεργές"</string>
<string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Αποσυνδεδεμένα"</string>
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Συσκευές ακοής"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Σύζευξη νέας συσκευής"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Προσθήκη περισσότερων γραφικών στοιχείων"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Παρατεταμένο πάτημα για προσαρμογή γραφ. στοιχείων"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Προσαρμογή γραφικών στοιχείων"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Εικονίδιο εφαρμογής για απενεργοποιημένο γραφικό στοιχείο"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Εικονίδιο εφαρμογής για ένα γραφικό στοιχείου που εγκαθίσταται"</string>
<string name="edit_widget" msgid="9030848101135393954">"Επεξεργασία γραφικού στοιχείου"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"επιλογή γραφικού στοιχείου"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"κατάργηση γραφικού στοιχείου"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"τοποθέτηση επιλεγμένου γραφικού στοιχείου"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Εναλλαγή χρήστη"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"αναπτυσσόμενο μενού"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Δεν υπάρχουν νέες ειδοποιήσεις"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Προσαρμοστ. ειδοπ. – Ενεργές"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Όταν λαμβάνετε πολλές ειδοποιήσεις σε σύντομο χρονικό διάστημα, η συσκευή θα χαμηλώνει την ένταση και θα μειώνει τα αναδυόμενα για έως και 2 λεπτά."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Απενεργοποίηση"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ξεκλειδώστε για εμφάνιση παλαιότ. ειδοπ."</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ο οργανισμός σας κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Πατήστε για περισσότερες πληροφορίες."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Δεν ορίστηκε ξυπνητ."</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"εισαγωγή κλειδώματος οθόνης"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Αγγίξτε τον αισθητήρα δακτυλικών αποτυπωμάτων. Είναι το πιο κοντό κουμπί στην πλευρά του τηλεφώνου."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Αισθητήρας δακτυλικών αποτυπωμάτων"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"έλεγχος ταυτότητας"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"εισαγωγή συσκευής"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Χρησιμοποιείται από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Χρησιμοποιήθηκε πρόσφατα από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Σύστημα"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Στοιχεία ελέγχου συστήματος"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Εφαρμογές συστήματος"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Πολυδιεργασία"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Πρόσφατες εφαρμογές"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Διαχωρισμός οθόνης"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Είσοδος"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Συντομεύσεις εφαρμογών"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Επιστροφή"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Για επιστροφή, σύρετε προς τα αριστερά ή προς τα δεξιά χρησιμοποιώντας τρία δάχτυλα οπουδήποτε στην επιφάνεια αφής."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Επιφάνεια αφής στην οποία εμφανίζονται τρία δάχτυλα να κινούνται δεξιά και αριστερά"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Οθόνη συσκευής που εμφανίζει μια κινούμενη εικόνα σχετικά με την κίνηση επιστροφής"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Οπίσθιος φωτισμός πληκτρολογίου"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Επίπεδο %1$d από %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Οικιακοί έλεγχοι"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 498031f..133c66d5 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to 2 minutes when you receive many notifications in a short time span."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It\'s the shorter button on the side of the phone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 8975cbf..40af8ce 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Screen Recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,10 +130,12 @@
<string name="screenrecord_stop_dialog_message" msgid="1926783607059442889">"You will stop recording your screen"</string>
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
<string name="share_to_app_stop_dialog_message" msgid="3181723638915877339">"You will stop sharing your screen"</string>
<string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="1910372600290258193">"Stop casting screen?"</string>
<string name="cast_to_other_device_stop_dialog_message" msgid="1502520537030715412">"You will stop casting your screen"</string>
<string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
@@ -181,6 +184,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognized. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel Authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More Options"</string>
@@ -460,6 +464,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -478,6 +484,9 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -531,6 +540,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to two minutes when you receive many notifications in a short time span."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organization owns this device and may monitor network traffic"</string>
@@ -1186,8 +1198,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It’s the shorter button on the side of the phone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1329,7 +1340,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1342,6 +1357,10 @@
<string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Home gesture"</string>
<string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using three fingers anywhere on the touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing three fingers moving right and left"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home Controls"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 498031f..133c66d5 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to 2 minutes when you receive many notifications in a short time span."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It\'s the shorter button on the side of the phone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 498031f..133c66d5 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to 2 minutes when you receive many notifications in a short time span."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It\'s the shorter button on the side of the phone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 179b792..52b567a 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Screen Recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,10 +130,12 @@
<string name="screenrecord_stop_dialog_message" msgid="1926783607059442889">"You will stop recording your screen"</string>
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
<string name="share_to_app_stop_dialog_message" msgid="3181723638915877339">"You will stop sharing your screen"</string>
<string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="1910372600290258193">"Stop casting screen?"</string>
<string name="cast_to_other_device_stop_dialog_message" msgid="1502520537030715412">"You will stop casting your screen"</string>
<string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
@@ -181,6 +184,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognized. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel Authentication"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More Options"</string>
@@ -460,6 +464,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -478,6 +484,9 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+ <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
+ <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
+ <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -531,6 +540,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to two minutes when you receive many notifications in a short time span."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organization owns this device and may monitor network traffic"</string>
@@ -1186,8 +1198,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It’s the shorter button on the side of the phone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1329,7 +1340,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1342,6 +1357,10 @@
<string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Home gesture"</string>
<string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using three fingers anywhere on the touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing three fingers moving right and left"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home Controls"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 0cad6b7..a5ccf57 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectó que tomaste una captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras apps en ejecución detectaron que tomaste una captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Agregar a la nota"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Grabadora de pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string>
@@ -129,24 +131,25 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Dejarás de grabar contenido de <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <!-- no translation found for share_to_app_chip_accessibility_label (4210256229976947065) -->
+ <skip />
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Dejarás de compartir contenido de <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <!-- no translation found for cast_to_other_device_chip_accessibility_label (1680650146639059938) -->
+ <skip />
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Dejarás de transmitir contenido de <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +198,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueo con rostro. Presiona para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rostro reconocido. Presiona para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rostro reconocido. Presiona el desbloqueo para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
@@ -309,10 +314,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Las funciones como Quick Share y Encontrar mi dispositivo usan Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"El Bluetooth se activará mañana a la mañana"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartir audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartiendo audio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string>
@@ -477,6 +480,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Agregar más widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén presionado para personalizar los widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícono de la app de widget inhabilitado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícono de la app para un widget que se está instalando"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modificar widget"</string>
@@ -495,6 +500,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Seleccionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú expandible"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
@@ -548,6 +559,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notific. adaptables activadas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tu dispositivo ahora baja el volumen y reduce las ventanas emergentes en la pantalla por hasta dos minutos si recibes muchas notificaciones en poco tiempo."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tu padre o madre administra este dispositivo"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tu organización es propietaria de este dispositivo y podría controlar el tráfico de red"</string>
@@ -1203,8 +1217,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Presiona para obtener más información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No establecida"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ingresa el bloqueo pantalla"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca el sensor de huellas dactilares. Es el botón más corto del lateral del teléfono"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de huellas dactilares"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ingresar al dispositivo"</string>
@@ -1346,7 +1359,15 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Uso reciente en <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <!-- no translation found for shortcut_helper_category_system_controls (3153344561395751020) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_category_system_apps (6001757545472556810) -->
+ <skip />
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Tareas múltiples"</string>
+ <!-- no translation found for shortcutHelper_category_recent_apps (7918731953612377145) -->
+ <skip />
+ <!-- no translation found for shortcutHelper_category_split_screen (1159669813444812244) -->
+ <skip />
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Accesos directos a aplicaciones"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
@@ -1363,6 +1384,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, desliza tres dedos hacia la derecha o izquierda en cualquier lugar del panel táctil."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil en el que aparecen tres dedos que se mueven hacia la derecha y la izquierda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla de un dispositivo en la que aparece una animación del gesto atrás"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 24638f5..28601fd 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectado esta captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras aplicaciones abiertas han detectado esta captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Añadir a nota"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Grabación de pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Dejarás de grabar <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartiendo pantalla"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Dejarás de compartir <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Enviando pantalla"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Dejarás de enviar <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado con la cara. Pulsa para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Cara reconocida. Pulsa para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Cara reconocida. Pulsa el icono de desbloquear para continuar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
@@ -391,7 +394,7 @@
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Grabar pantalla"</string>
<string name="performance" msgid="6552785217174378320">"Rendimiento"</string>
<string name="user_interface" msgid="3712869377953950887">"Interfaz de usuario"</string>
- <string name="thermal" msgid="6758074791325414831">"Térmico"</string>
+ <string name="thermal" msgid="6758074791325414831">"Temperatura"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo Una mano"</string>
<string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Audífonos"</string>
<string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Activos"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Añade más widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén pulsado para personalizar los widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icono de la aplicación de widget inhabilitado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Instalando icono de aplicación para widget"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eliminar widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notif. adaptativas activadas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tu dispositivo baja el volumen y reduce las ventanas emergentes durante un máximo de 2 minutos cuando recibes muchas notificaciones en poco tiempo."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo lo gestionan tu padre o tu madre"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"El dispositivo pertenece a tu organización, que puede monitorizar su tráfico de red"</string>
@@ -679,7 +693,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Se ha producido un problema al obtener tus tarjetas. Inténtalo de nuevo más tarde."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ajustes de pantalla de bloqueo"</string>
- <string name="qr_code_scanner_title" msgid="1938155688725760702">"Escáner de códigos QR"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Escáner QR"</string>
<string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Actualizando"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo Avión"</string>
@@ -1045,7 +1059,7 @@
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Quitar"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Control disposit."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Quitado"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca la pantalla para consultar más información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ninguna puesta"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"Poner bloqueo de pantalla"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca el sensor de huellas digitales. Es el botón más pequeño del lateral del teléfono."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de huellas digitales"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticarte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acceder al dispositivo"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recientemente por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles del sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicaciones del sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarea"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicaciones recientes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Accesos directos a aplicaciones"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, desliza tres dedos hacia la izquierda o la derecha en cualquier punto del panel táctil."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil con tres dedos moviéndose hacia la derecha y la izquierda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla del dispositivo que muestra una animación del gesto para volver atrás"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 8169e82..60a1fbf 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> tuvastas selle ekraanipildi."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja muud avatud rakendused tuvastasid selle ekraanipildi."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisa märkmesse"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Ekraanisalvesti"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Lõpetate rakenduse <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sisu salvestamise"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekraani jagamine"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Lõpetate rakenduse <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sisu jagamise"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekraanikuva ülekandmine"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Lõpetate rakenduse <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sisu ülekandmise"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avati näoga. Vajutage jätkamiseks."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nägu tuvastati. Vajutage jätkamiseks."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nägu tuvastati. Jätkamiseks vajutage avamise ikooni."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Tühista autentimine"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Rohkem valikuid"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Sellised funktsioonid nagu Kiirjagamine ja Leia mu seade kasutavad Bluetoothi."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth lülitub sisse homme hommikul"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Jaga heli"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Heli jagamine"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> akut"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Heli"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Peakomplekt"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisage rohkem vidinaid"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vajutage pikalt vidinate kohandamiseks"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Kohanda vidinaid"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Keelatud vidina rakenduseikoon"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Installitava vidina rakenduseikoon"</string>
<string name="edit_widget" msgid="9030848101135393954">"Muuda vidinat"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidina valimine"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eemaldage vidin"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"asetage valitud vidin"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rippmenüü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Märguandeid pole"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Uusi märguandeid ei ole"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Kohanduvad märguanded on sees"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Seade vähendab nüüd helitugevust ja ekraanil kuvatavaid hüpikaknaid kuni kaheks minutiks, kui saate lühikese aja jooksul palju märguandeid."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Lülita välja"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vanemate märguannete nägemiseks avage"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Seda seadet haldab sinu vanem"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Teie organisatsioon on selle seadme omanik ja võib jälgida võrguliiklust"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Puudutage lisateabe saamiseks"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Äratust pole"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"sisesta ekraanilukk"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Puudutage sõrmejäljeandurit. See on lühem nupp telefoni küljel."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sõrmejäljeandur"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentimiseks"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"seadmesse sisenemiseks"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Seda kasutab <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kasutas hiljuti rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Süsteem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Süsteemi juhtelemendid"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Süsteemirakendused"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitegumtöö"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Hiljutised rakendused"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Jagatud ekraanikuva"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Sisend"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Rakenduse otseteed"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tagasi"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Tagasiliikumiseks pühkige puuteplaadil kolme sõrmega vasakule või paremale."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Puuteplaat kolme paremale ja vasakule liikuva sõrmega"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Seadme ekraanil näidatakse tagasiliigutuse animatsiooni"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatuuri taustavalgustus"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tase %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kodu juhtelemendid"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index e9e8518..2ba8a63 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak pantaila-argazkia hauteman du."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak eta irekitako beste aplikazio batzuek pantaila-argazkia hauteman dute."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Gehitu oharrean"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Pantaila-grabagailua"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> grabatzeari utziko diozu"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Pantaila partekatzen"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> partekatzeari utziko diozu"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Pantaila igortzen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> igortzeari utziko diozu"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Aurpegiaren bidez desblokeatu da. Sakatu aurrera egiteko."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ezagutu da aurpegia. Sakatu aurrera egiteko."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ezagutu da aurpegia. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Utzi bertan behera autentifikazioa"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Aukera gehiago"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Gehitu widget gehiago"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widgetak pertsonalizatzeko, sakatu luze"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pertsonalizatu widgetak"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Desgaitutako widgetaren aplikazio-ikonoa"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Instalatzen ari den widget bati dagokion aplikazioaren ikonoa"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editatu widgeta"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"hautatu widget bat"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"kendu widgeta"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kokatu hautatutako widgeta"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"zabaldu menua"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ez dago jakinarazpen berririk"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Jakinarazpen egokituak aktibatuta"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Epe labur batean jakinarazpen ugari jasotzen badituzu, bolumena jaitsi, eta pantailako leiho gainerakorrak murriztuko ditu gailuak orain, gehienez 2 minutuz."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desaktibatu"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Jakinarazpen zaharragoak ikusteko, desblokeatu"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Zure gurasoak kudeatzen du gailua"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Gailu hau zure erakundearena da, eta baliteke hark sareko trafikoa gainbegiratzea"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarmarik ez"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"erabili pantailaren blokeoa"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Ukitu hatz-marken sentsorea. Pantailaren albo batean dagoen botoi laburra da."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Hatz-marken sentsorea"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatu"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"sartu gailuan"</string>
@@ -1326,7 +1339,7 @@
<string name="dismiss_dialog" msgid="2195508495854675882">"Baztertu"</string>
<string name="connected_display_icon_desc" msgid="6373560639989971997">"Konektatutako pantaila"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonoa eta kamera"</string>
- <string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikazioen azken erabilera"</string>
+ <string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikazioen azkenaldiko erabilera"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ikusi azkenaldiko sarbidea"</string>
<string name="privacy_dialog_done_button" msgid="4504330708531434263">"Eginda"</string>
<string name="privacy_dialog_expand_action" msgid="9129262348628331377">"Zabaldu eta erakutsi aukerak"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak darabil (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) aplikazioak erabili du duela gutxi"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistema kontrolatzeko aukerak"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemaren aplikazioak"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Zeregin bat baino gehiago aldi berean exekutatzea"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Azkenaldiko aplikazioak"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantaila zatitzea"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Sarrera"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Aplikazioetarako lasterbideak"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Egin atzera"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Atzera egiteko, pasatu 3 hatz ezkerrera edo eskuinera ukipen-panelean."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"3 hatz ukipen-panel baten gainean eskuinera eta ezkerrera mugitzen erakusten duen irudia"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Gailuaren pantailan atzera egiteko keinuaren animazioa erakusten duen irudia"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Teklatuaren hondoko argia"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d/%2$d maila"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Etxeko gailuen kontrola"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 3e876ad..7300d2c 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"«<xliff:g id="APPNAME">%1$s</xliff:g>» این نماگرفت را تشخیص داد."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> و سایر برنامههای باز این نماگرفت را تشخیص دادند."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"افزودن به یادداشت"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"ضبطکن صفحهنمایش"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحهنمایش"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحهنمایش"</string>
@@ -122,31 +124,30 @@
<string name="screenrecord_stop_label" msgid="72699670052087989">"متوقف کردن"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"همرسانی"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"قطعه ضبطشده از صفحهنمایش ذخیره شد"</string>
- <string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده ضربه بزنید"</string>
+ <string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده تکضرب بزنید"</string>
<string name="screenrecord_save_error" msgid="5862648532560118815">"خطا در ذخیرهسازی ضبط صفحهنمایش"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحهنمایش"</string>
<!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ضبط <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> را متوقف خواهید کرد"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"درحال همرسانی صفحهنمایش"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"همرسانی <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> را متوقف خواهید کرد"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"درحال پخش محتوای صفحهنمایش"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"پخش محتوای <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> را متوقف خواهید کرد"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -157,7 +158,7 @@
<string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"درحال ضبط کردن مشکل"</string>
<string name="issuerecord_share_label" msgid="3992657993619876199">"همرسانی"</string>
<string name="issuerecord_save_title" msgid="4161043023696751591">"ضبط مشکل ذخیره شد"</string>
- <string name="issuerecord_save_text" msgid="1205985304551521495">"برای مشاهده ضربه بزنید"</string>
+ <string name="issuerecord_save_text" msgid="1205985304551521495">"برای مشاهده تکضرب بزنید"</string>
<string name="issuerecord_save_error" msgid="6913040083446722726">"هنگام ذخیره کردن ضبط مشکل، خطایی پیش آمد"</string>
<string name="issuerecord_start_error" msgid="3402782952722871190">"هنگام شروع ضبط مشکل، خطایی پیش آمد"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"درحال مشاهده در حالت تمامصفحه"</string>
@@ -185,16 +186,18 @@
</string-array>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأیید"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"امتحان مجدد"</string>
- <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"برای لغو راستیآزمایی ضربه بزنید"</string>
+ <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"برای لغو راستیآزمایی تکضرب بزنید"</string>
<string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"لطفاً دوباره امتحان کنید"</string>
<string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"درحال جستجوی چهره"</string>
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چهره اصالتسنجی شد"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
- <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
+ <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید تکضرب بزنید"</string>
<string name="biometric_dialog_tap_confirm_with_face" msgid="2378151312221818694">"قفل با چهره باز شد"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"قفلْ با چهره باز شد. برای ادامه، فشار دهید."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چهره شناسایی شد. برای ادامه، فشار دهید."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چهره شناسایی شد. برای ادامه، نماد قفلگشایی را فشار دهید."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستیآزماییشده"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"لغو اصالتسنجی"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"گزینههای بیشتر"</string>
@@ -296,7 +299,7 @@
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"مزاحم نشوید"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"هیچ دستگاه مرتبط شدهای موجود نیست"</string>
- <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"برای اتصال یا قطع اتصال دستگاه، ضربه بزنید"</string>
+ <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"برای اتصال یا قطع اتصال دستگاه، تکضرب بزنید"</string>
<string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"جفت کردن دستگاه جدید"</string>
<string name="see_all_bluetooth_devices" msgid="1761596816620200433">"دیدن همه"</string>
<string name="turn_on_bluetooth" msgid="5681370462180289071">"استفاده از بلوتوث"</string>
@@ -435,8 +438,8 @@
<string name="zen_priority_customize_button" msgid="4119213187257195047">"سفارشی کردن"</string>
<string name="zen_silence_introduction_voice" msgid="853573681302712348">"این کار «همه» صداها و لرزشها (شامل هشدار، موسیقی، ویدیو و بازی) را مسدود میکند. همچنان میتوانید تماس تلفنی برقرار کنید."</string>
<string name="zen_silence_introduction" msgid="6117517737057344014">"این کار «همه» صداها و لرزشها از جمله هشدارها، موسیقی، ویدئوها و بازیها را مسدود میکند."</string>
- <string name="notification_tap_again" msgid="4477318164947497249">"دوباره ضربه بزنید تا باز شود"</string>
- <string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string>
+ <string name="notification_tap_again" msgid="4477318164947497249">"دوباره تکضرب بزنید تا باز شود"</string>
+ <string name="tap_again" msgid="1315420114387908655">"دوباره تکضرب بزنید"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند بهبالا بکشید"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"برای باز کردن، نماد قفلگشایی را فشار دهید"</string>
<string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"قفلْ با چهره باز شد. برای باز کردن، تند بهبالا بکشید."</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"افزودن ابزارکهای بیشتر"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"برای سفارشیسازی ابزارکها، فشار طولانی دهید"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"سفارشیسازی ابزارکها"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"نماد برنامه برای ابزارک غیرفعال"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"نماد برنامه مربوط به ابزارکی که درحال نصب است"</string>
<string name="edit_widget" msgid="9030848101135393954">"ویرایش ابزارک"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"انتخاب ابزارک"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"برداشتن ابزارک"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"جایگذاری ابزارک انتخابشده"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"منوی پایینپر"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامهها و دادههای این جلسه حذف خواهد شد."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"اکنون شروع کنید"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"اعلانی موجود نیست"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"اعلان جدیدی وجود ندارد"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"اعلانهای تطبیقی روشن است"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ازاینپس هروقت اعلانهای زیادی در یک بازه زمانی کوتاه دریافت کنید، دستگاهتان تا دو دقیقه صدا را کم میکند و تعداد پنجرههای بالاپر را در صفحهنمایش کاهش میدهد."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"خاموش کردن"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"برای دیدن اعلانهای قبلی قفل را باز کنید"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"این دستگاه را ولیتان مدیریت میکند"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"مالک این دستگاه سازمان شما است و ممکن است ترافیک شبکه را پایش کند"</string>
@@ -638,17 +652,17 @@
<string name="stream_notification_unavailable" msgid="4313854556205836435">"دردسترس نیست، چون زنگ بیصدا شده است"</string>
<string name="stream_alarm_unavailable" msgid="4059817189292197839">"دردسترس نیست زیرا «مزاحم نشوید» روشن است"</string>
<string name="stream_media_unavailable" msgid="6823020894438959853">"دردسترس نیست زیرا «مزاحم نشوید» روشن است"</string>
- <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. برای باصدا کردن ضربه بزنید."</string>
- <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. برای تنظیم روی لرزش ضربه بزنید. ممکن است سرویسهای دسترسپذیری بیصدا شوند."</string>
- <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. برای صامت کردن ضربه بزنید. ممکن است سرویسهای دسترسپذیری صامت شود."</string>
- <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. برای تنظیم روی لرزش، ضربه بزنید."</string>
- <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. برای صامت کردن ضربه بزنید."</string>
+ <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. برای باصدا کردن تکضرب بزنید."</string>
+ <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. برای تنظیم روی لرزش تکضرب بزنید. ممکن است سرویسهای دسترسپذیری بیصدا شوند."</string>
+ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. برای صامت کردن تکضرب بزنید. ممکن است سرویسهای دسترسپذیری صامت شود."</string>
+ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. برای تنظیم روی لرزش، تکضرب بزنید."</string>
+ <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. برای صامت کردن تکضرب بزنید."</string>
<string name="volume_panel_noise_control_title" msgid="7413949943872304474">"کنترل صدای محیط"</string>
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"صدای فضایی"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"خاموش"</string>
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ثابت"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ردیابی سر"</string>
- <string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، ضربه بزنید"</string>
+ <string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، تکضرب بزنید"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"لرزش"</string>
@@ -674,7 +688,7 @@
<string name="wallet_title" msgid="5369767670735827105">"کیف پول"</string>
<string name="wallet_empty_state_label" msgid="7776761245237530394">"برای خرید سریعتر و امنتر با تلفن، راهاندازی کنید"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"نمایش همه"</string>
- <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"برای باز کردن ضربه بزنید"</string>
+ <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"برای باز کردن تکضرب بزنید"</string>
<string name="wallet_secondary_label_updating" msgid="5726130686114928551">"درحال بهروزرسانی"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"برای استفاده، قفل را باز کنید"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"هنگام دریافت کارتها مشکلی پیش آمد، لطفاً بعداً دوباره امتحان کنید"</string>
@@ -940,7 +954,7 @@
<string name="instant_apps" msgid="8337185853050247304">"برنامههای فوری"</string>
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> درحال اجرا"</string>
<string name="instant_apps_message" msgid="6112428971833011754">"برنامه بدون نصب شدن باز شد."</string>
- <string name="instant_apps_message_with_help" msgid="1816952263531203932">"برنامه بدون نصب شدن باز شد. برای اطلاعات بیشتر ضربه بزنید."</string>
+ <string name="instant_apps_message_with_help" msgid="1816952263531203932">"برنامه بدون نصب شدن باز شد. برای اطلاعات بیشتر تکضرب بزنید."</string>
<string name="app_info" msgid="5153758994129963243">"اطلاعات برنامه"</string>
<string name="go_to_web" msgid="636673528981366511">"رفتن به مرورگر"</string>
<string name="mobile_data" msgid="4564407557775397216">"داده تلفن همراه"</string>
@@ -954,7 +968,7 @@
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"برنامهای (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"برنامه یا قانون خودکاری، «مزاحم نشوید» را روشن کرد."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"برنامههایی که در پسزمینه اجرا میشوند"</string>
- <string name="running_foreground_services_msg" msgid="3009459259222695385">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
+ <string name="running_foreground_services_msg" msgid="3009459259222695385">"برای جزئیات مربوط به مصرف باتری و داده، تکضرب بزنید"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"داده تلفن همراه خاموش شود؟"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"نمیتوانید ازطریق <xliff:g id="CARRIER">%s</xliff:g> به داده یا اینترنت دسترسی داشته باشید. اینترنت فقط ازطریق Wi-Fi در دسترس خواهد بود."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"شرکت مخابراتی شما"</string>
@@ -969,7 +983,7 @@
<string name="slice_permission_checkbox" msgid="4242888137592298523">"به <xliff:g id="APP">%1$s</xliff:g> اجازه داده شود تکههایی از برنامهها نشان دهد"</string>
<string name="slice_permission_allow" msgid="6340449521277951123">"اجازه دادن"</string>
<string name="slice_permission_deny" msgid="6870256451658176895">"مجاز نبودن"</string>
- <string name="auto_saver_title" msgid="6873691178754086596">"برای زمانبندی «بهینهسازی باتری» ضربه بزنید"</string>
+ <string name="auto_saver_title" msgid="6873691178754086596">"برای زمانبندی «بهینهسازی باتری» تکضرب بزنید"</string>
<string name="auto_saver_text" msgid="3214960308353838764">"وقتی باتری روبهاتمام است، بهینهسازی باتری را روشن کنید"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"نه متشکرم"</string>
<string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"استفاده شده"</string>
@@ -1029,11 +1043,11 @@
<string name="accessibility_magnification_done" msgid="263349129937348512">"تمام"</string>
<string name="accessibility_magnifier_edit" msgid="1522877239671820636">"ویرایش"</string>
<string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"تنظیمات پنجره ذرهبین"</string>
- <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"برای باز کردن ویژگیهای دسترسپذیری ضربه بزنید. در تنظیمات این دکمه را سفارشی یا جایگزین کنید\n\n"<annotation id="link">"تنظیمات"</annotation></string>
+ <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"برای باز کردن ویژگیهای دسترسپذیری تکضرب بزنید. در تنظیمات این دکمه را سفارشی یا جایگزین کنید\n\n"<annotation id="link">"تنظیمات"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"برای پنهان کردن موقتی دکمه، آن را به لبه ببرید"</string>
<string name="accessibility_floating_button_undo" msgid="511112888715708241">"واگرد"</string>
<string name="accessibility_floating_button_hidden_notification_title" msgid="4115036997406994799">"دکمه دسترسپذیری پنهان شده است"</string>
- <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"برای نمایش دکمه دسترسپذیری ضربه بزنید"</string>
+ <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"برای نمایش دکمه دسترسپذیری تکضرب بزنید"</string>
<string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"میانبر «<xliff:g id="FEATURE_NAME">%s</xliff:g>» برداشته شد"</string>
<string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{میانبر «#» برداشته شد}one{میانبر «#» برداشته شد}other{میانبر «#» برداشته شد}}"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"انتقال به بالا سمت راست"</string>
@@ -1134,7 +1148,7 @@
<string name="media_output_dialog_single_device" msgid="3102758980643351058">"۱ دستگاه انتخاب شد"</string>
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> دستگاه انتخاب شد"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(اتصال قطع شد)"</string>
- <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"عوض نمیشود. برای تلاش مجدد ضربه بزنید."</string>
+ <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"عوض نمیشود. برای تلاش مجدد تکضرب بزنید."</string>
<string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"متصل کردن دستگاه"</string>
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string>
@@ -1163,7 +1177,7 @@
<string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریدهدان کپی شد."</string>
<string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ابزارکهای مکالمه"</string>
- <string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمهای ضربه بزنید تا به «صفحه اصلی» اضافه شود"</string>
+ <string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمهای تکضرب بزنید تا به «صفحه اصلی» اضافه شود"</string>
<string name="no_conversations_text" msgid="5354115541282395015">"آخرین مکالمههای شما اینجا نشان داده میشود"</string>
<string name="priority_conversations" msgid="3967482288896653039">"مکالمههای اولویتدار"</string>
<string name="recent_conversations" msgid="8531874684782574622">"گفتگوهای اخیر"</string>
@@ -1198,11 +1212,10 @@
<string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> وضعیتش را بهروزرسانی کرد: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
<string name="person_available" msgid="2318599327472755472">"دردسترس"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"مشکلی در خواندن میزان باتری وجود دارد"</string>
- <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر ضربه بزنید"</string>
+ <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر تکضرب بزنید"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"هشداری تنظیم نشده"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"وارد کردن قفل صفحه"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"حسگر اثر انگشت را لمس کنید. این حسگر همان دکمه کوچکتر در کنار تلفن است"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"حسگر اثرانگشت"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"اصالتسنجی کردن"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"وارد شدن به دستگاه"</string>
@@ -1219,7 +1232,7 @@
<string name="non_carrier_network_unavailable" msgid="770049357024492372">"شبکه دیگری وجود ندارد"</string>
<string name="all_network_unavailable" msgid="4112774339909373349">"شبکهای در دسترس نیست"</string>
<string name="turn_on_wifi" msgid="1308379840799281023">"Wi-Fi"</string>
- <string name="tap_a_network_to_connect" msgid="1565073330852369558">"برای اتصال به شبکه روی آن ضربه بزنید"</string>
+ <string name="tap_a_network_to_connect" msgid="1565073330852369558">"برای اتصال به شبکه روی آن تکضرب بزنید"</string>
<string name="unlock_to_view_networks" msgid="5072880496312015676">"برای مشاهده شبکهها، قفل صفحه را باز کنید"</string>
<string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"درحال جستجوی شبکه…"</string>
<string name="wifi_failed_connect_message" msgid="4161863112079000071">"اتصال به شبکه برقرار نشد"</string>
@@ -1245,7 +1258,7 @@
<string name="clipboard_edit_text_description" msgid="805254383912962103">"ویرایش نوشتار کپیشده"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"ویرایش تصویر کپیشده"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ارسال به دستگاهی در اطراف"</string>
- <string name="clipboard_text_hidden" msgid="7926899867471812305">"برای مشاهده، ضربه بزنید"</string>
+ <string name="clipboard_text_hidden" msgid="7926899867471812305">"برای مشاهده، تکضرب بزنید"</string>
<string name="clipboard_text_copied" msgid="5100836834278976679">"نوشتار کپی شد"</string>
<string name="clipboard_image_copied" msgid="3793365360174328722">"تصویر کپی شد"</string>
<string name="clipboard_content_copied" msgid="144452398567828145">"محتوا کپی شد"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> از آن استفاده میکند (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"اخیراً <xliff:g id="APP_NAME">%1$s</xliff:g> از آن استفاده کرده است (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"سیستم"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"کنترلهای سیستم"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"برنامههای سیستم"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"چندوظیفگی"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"برنامههای اخیر"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"صفحهٔ دونیمه"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ورودی"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"میانبرهای برنامه"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترسپذیری"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"برگشتن"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"برای برگشتن، در هر جایی از صفحه لمسی، با سه انگشت تند بهچپ یا راست بکشید."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"صفحه لمسی که سه انگشت را درحال حرکت بهسمت راست و چپ نشان میدهد"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"صفحهنمایش دستگاه درحال نمایش پویانمایی مربوط به اشاره برگشتن"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پسزمینه صفحهکلید"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"سطح %1$d از %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"کنترل خانه هوشمند"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 2291d19..f01e6c0 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> havaitsi tämän kuvakaappauksen."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja jotkin muut sovellukset havaitsivat tämän kuvakaappauksen."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisää muistiinpanoon"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Näytön tallentaja"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ei enää tallenna sisältöä"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Näyttöä jaetaan"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ei enää jaa sisältöä"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Näyttöä striimataan"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ei enää striimaa sisältöä"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avattu kasvojen avulla. Jatka painamalla."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Kasvot tunnistettu. Jatka painamalla."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Peruuta todennus"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lisää vaihtoehtoja"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, Paikanna laite ja tietyt muut ominaisuudet käyttävät Bluetoothia"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth menee päälle huomisaamuna"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Jaa audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audiota jaetaan"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ääni"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisää widgetejä"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Yksilöi widgetit pitkällä painalluksella"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Muokkaa widgettejä"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Käytöstä poistetun widgetin sovelluskuvake"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Sovelluskuvake widgetin asentamisesta"</string>
<string name="edit_widget" msgid="9030848101135393954">"Muokkaa widgetiä"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"valitse widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"poista widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"aseta valittu widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"alasvetovalikko"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ei uusia ilmoituksia"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Mukautuvat ilmoitukset päällä"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Laite vähentää nyt äänenvoimakkuutta ja ponnahdusikkunoiden määrää enintään kahdeksi minuutiksi, kun saat monta ilmoitusta lyhyellä aikavälillä."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Laita pois päältä"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Avaa lukitus niin näet ilmoituksia"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Vanhempasi ylläpitää tätä laitetta"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisaatiosi omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
@@ -820,8 +832,8 @@
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Syöttötapa"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Vaihda seuraavaan kieleen"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Vaihda aiempaan kieleen"</string>
- <string name="input_access_emoji" msgid="8105642858900406351">"Emojien käyttö"</string>
- <string name="input_access_voice_typing" msgid="7291201476395326141">"Puhekirjoituksen käyttö"</string>
+ <string name="input_access_emoji" msgid="8105642858900406351">"Käytä emojeja"</string>
+ <string name="input_access_voice_typing" msgid="7291201476395326141">"Käytä puhekirjoitusta"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Sovellukset"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Selain"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Saat lisätietoja napauttamalla"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ei herätyksiä"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"käytä näytön lukitustapaa"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Kosketa sormenjälkitunnistinta. Se on puhelimen sivussa oleva lyhyempi painike."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sormenjälkitunnistin"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"todentaaksesi"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"avataksesi laitteen"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Tämän käytössä: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> käytti tätä äskettäin (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Järjestelmä"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Järjestelmän hallinta"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Järjestelmäsovellukset"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitaskaus"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Viimeisimmät sovellukset"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Jaettu näyttö"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Syöte"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Sovellusten pikakuvakkeet"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Takaisin"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Jos haluat siirtyä takaisin, pyyhkäise kosketuslevyllä vasemmalle tai oikealle kolmella sormella."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Kosketuslevy, jolla kolme sormea liikkuu oikealle ja vasemmalle"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Laitteen näyttö, jolla näkyy animaatio takaisin-eleestä"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Näppämistön taustavalo"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Taso %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kodin ohjaus"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index fbd16d4..d2adbf6 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applications ouvertes ont détecté cette capture d\'écran."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à une note"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vous arrêterez d\'enregistrer <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage d\'écran en cours…"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vous arrêterez de partager <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Diffusion de l\'écran en cours…"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vous arrêterez de diffuser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverr. par reconnaissance faciale. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur Déverrouiller pour continuer."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Les fonctionnalités comme Partage rapide et Localiser mon appareil utilisent le Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Le Bluetooth s\'activera demain matin"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partager l\'audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Partage de l\'audio en cours…"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Écouteurs"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter plus de widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Maintenez le doigt pour personnaliser les widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'application pour un widget désactivé"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icône d\'appli indiquant qu\'un widget est en cours d\'installation"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner le widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"retirer le widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer le widget sélectionné"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifications adaptatives actives"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Votre appareil réduit le volume et les fenêtres contextuelles à l\'écran pendant 2 minutes max. quand vous recevez plusieurs notifications rapidement."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverr. pour voir les anciennes notif."</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par ton parent"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Votre organisation possède cet appareil et peut contrôler le trafic réseau"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Touchez pour en savoir plus"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Aucune alarme définie"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"entrer verrouillage de l\'écran"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toucher le capteur d\'empreintes digitales. Il s\'agit du bouton le plus court sur le côté du téléphone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Capteur d\'empreintes digitales"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"authentifier"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Récemment utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Système"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Commandes système"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Applis système"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitâche"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Applis récentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Écran divisé"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrée"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Raccourcis des applis"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pour revenir en arrière, balayez vers la gauche ou la droite en utilisant trois doigts n\'importe où sur le pavé tactile."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pavé tactile montrant trois doigts se déplaçant à droite et à gauche"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Écran de l\'appareil montrant l\'animation pour le geste de retour"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Domotique"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 55c39dc..45e5c02 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applis ouvertes ont détecté cette capture d\'écran."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à la note"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vous arrêterez d\'enregistrer <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage de l\'écran…"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vous arrêterez de partager <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Diffusion de l\'écran…"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vous arrêterez de caster <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverrouillé par visage. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Certaines fonctionnalités, telles que Quick Share et Localiser mon appareil, utilisent le Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Le Bluetooth sera activé demain matin"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partager le contenu audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio partagé"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Casque"</string>
@@ -385,7 +386,7 @@
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Démarrer"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Arrêter"</string>
<string name="qs_record_issue_label" msgid="8166290137285529059">"Enregistrer le problème"</string>
- <string name="qs_record_issue_start" msgid="2979831312582567056">"Début"</string>
+ <string name="qs_record_issue_start" msgid="2979831312582567056">"Lancer"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Arrêter"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Rapport de bug"</string>
<string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Quel problème avez-vous rencontré avec votre appareil ?"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter des widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Appuyez de manière prolongée pour personnaliser les widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'appli du widget désactivé"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icône d\'application indiquant qu\'un widget est en cours d\'installation"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner un widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"supprimer le widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"positionner le widget sélectionné"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Les notifications intelligentes sont activées"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Désormais, lorsque vous recevez de nombreuses notifications en peu de temps, votre appareil baisse le volume et réduit les pop-up qui apparaissent à l\'écran pendant deux minutes maximum."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverrouiller pour voir anciennes notifications"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par tes parents"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Cet appareil appartient à votre organisation, qui peut contrôler votre trafic réseau"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Appuyer pour en savoir plus"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Pas d\'alarme définie"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"accéder au verrouillage de l\'écran"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Appuyez sur le lecteur d\'empreinte digitale. Il s\'agit du plus petit bouton sur le côté du téléphone."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Lecteur d\'empreinte digitale"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"s\'authentifier"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En cours d\'utilisation par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Récemment utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Système"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Commandes système"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Applis système"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitâche"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Applis récentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Écran partagé"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrée"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Raccourcis d\'application"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pour retourner en arrière, balayez vers la gauche avec trois doigts n\'importe où sur le pavé tactile."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pavé tactile sur lequel trois doigts glissent vers la droite, puis vers la gauche"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Écran d\'un appareil affichant l\'animation du geste Retour"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d sur %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Contrôle de la maison"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index a85b9ec..99e9b78 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectou esta captura de pantalla."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outras aplicacións abertas detectaron esta captura de pantalla."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engadir a unha nota"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Gravadora da pantalla"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación de actividade en curso sobre unha sesión de gravación de pantalla"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Deixarás de gravar a aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartindo pantalla"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Deixarás de compartir a aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Emitindo pantalla"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Deixarás de emitir a aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Usouse o desbloqueo facial. Preme para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Recoñeceuse a cara. Preme para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Recoñeceuse a cara. Preme a icona de desbloquear."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar a autenticación"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Máis opcións"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"As funcións como Quick Share e Localizar o meu dispositivo utilizan o Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth activarase mañá á mañá"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartir audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartindo audio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engadir máis widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pulsación longa para personalizar os widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona da aplicación de widget desactivado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona da aplicación para un widget que se está instalando"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar o widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar o widget seleccionado"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú despregable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Non hai notificacións"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Non hai notificacións novas"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificacións intelix. activas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O dispositivo baixa o volume e reduce as ventás emerxentes na pantalla durante 2 min como máximo cando recibes moitas notificacións en pouco tempo."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver máis notificacións"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"O teu pai ou nai xestiona este dispositivo"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A túa organización é propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca para obter máis información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Sen alarmas postas"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"introducir o bloqueo de pantalla"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca o sensor de impresión dixital. É o botón máis pequeno no lateral do teléfono"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impresión dixital"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"poñer o dispositivo"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"En uso recentemente por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controis do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicacións do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefa"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicacións recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atallos de aplicacións"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Volver"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, pasa tres dedos cara á esquerda ou cara á dereita en calquera lugar do panel táctil."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil que mostra tres dedos movéndose á dereita e á esquerda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla do dispositivo que mostra unha animación do xesto de retroceso"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controis domóticos"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 11846b3..cedcaa1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> અને કામ કરતી અન્ય ઍપ દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"નોંધમાં ઉમેરો"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"સ્ક્રીન રેકોર્ડર"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"તમે <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને રેકોર્ડ કરવાનું બંધ કરશો"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"સ્ક્રીન શેર કરી રહ્યાં છીએ"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"તમે <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને શેર કરવાનું બંધ કરશો"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"સ્ક્રીન કાસ્ટ કરી રહ્યાં છીએ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"તમે <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને કાસ્ટ કરવાનું બંધ કરશો"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા માટે દબાવો."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ચહેરો ઓળખ્યો. આગળ વધવા માટે દબાવો."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ચહેરો ઓળખ્યો. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"પ્રમાણીકરણ રદ કરો"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"વધુ વિકલ્પો"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"વધુ વિજેટ ઉમેરો"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"વિજેટ કસ્ટમાઇઝ કરવા માટે થોડીવાર દબાવી રાખો"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"વિજેટ કસ્ટમાઇઝ કરો"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"બંધ કરેલા વિજેટ માટેની ઍપનું આઇકન"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ઇન્સ્ટૉલ થઈ રહેલા વિજેટ માટે ઍપનું આઇકન"</string>
<string name="edit_widget" msgid="9030848101135393954">"વિજેટમાં ફેરફાર કરો"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"વિજેટ પસંદ કરો"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"વિજેટ કાઢી નાખો"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"પસંદ કરેલું વિજેટ મૂકો"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"પુલડાઉન મેનૂ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"હવે શરૂ કરો"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"કોઈ નોટિફિકેશન નથી"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"કોઈ નવું નોટિફિકેશન નથી"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"અડૅપ્ટિવ નોટિફિકેશન ચાલુ છે"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"તમને ટૂંકા સમયગાળામાં ઘણાં નોટિફિકેશન મળે, ત્યારે ડિવાઇસ બે મિનિટ સુધી વૉલ્યૂમ ઓછું કરે છે અને સ્ક્રીન પરના પૉપ-અપની સંખ્યા ઓછી કરે છે."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"બંધ કરો"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"જૂના નોટિફિકેશન જોવા માટે અનલૉક કરો"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"તમારી સંસ્થા આ ડિવાઇસની માલિકી ધરાવે છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"વધુ માહિતી માટે ટૅપ કરો"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"કોઈ અલાર્મ સેટ નથી"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"સ્ક્રીન લૉક દાખલ કરો"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ફિંગરપ્રિન્ટ સેન્સરને ટચ કરો. ફોનની બાજુમાં આવેલું આ કોઈ નાનું બટન છે"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ફિંગરપ્રિન્ટ સેન્સર"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ખાતરી કરો"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ડિવાઇસ અનલૉક કરો"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) દ્વારા ઉપયોગ ચાલુ છે"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) દ્વારા તાજેતરમાં ઉપયોગ કરવામાં આવ્યો"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"સિસ્ટમ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"સિસ્ટમના નિયંત્રણો"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"સિસ્ટમ ઍપ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"એકથી વધુ કાર્યો કરવા"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"તાજેતરની ઍપ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"સ્ક્રીનને વિભાજિત કરો"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ઇનપુટ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ઍપ શૉર્ટકટ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"પાછા જાઓ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"પાછા જવા માટે, ત્રણ આંગળીઓનો ઉપયોગ કરીને ટચપૅડ પર કોઈપણ જગ્યાએ ડાબે કે જમણે સ્વાઇપ કરો."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"જમણી અને ડાબી તરફ ખસી રહેલી ત્રણ આંગળીઓ બતાવતું ટચપૅડ"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"પાછા જવા માટેના સંકેત માટેનું ઍનિમેશન બતાવતી ડિવાઇસ સ્ક્રીન"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ઘરેલું સાધનોના નિયંત્રણો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index dcd3b6c..591ad10 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> को इस स्क्रीनशॉट का पता चला है."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> और खुले हुए अन्य ऐप्लिकेशन को इस स्क्रीनशॉट का पता चला है."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोट में जोड़ें"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"लिंक जोड़ें"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रिकॉर्डर"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"इससे <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> का कॉन्टेंट रिकॉर्ड होना बंद हो जाएगा"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेयर की जा रही है"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"इससे <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> का कॉन्टेंट शेयर होना बंद हो जाएगा"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"स्क्रीन कास्ट की जा रही है"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"इससे <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> का कॉन्टेंट कास्ट होना बंद हो जाएगा"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरे की पहचान हो गई. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"पुष्टि करने की प्रोसेस को रद्द करें"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ज़्यादा विकल्प"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक शेयर और Find My Device जैसी सुविधाएं, ब्लूटूथ का इस्तेमाल करती हैं"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लूटूथ कल सुबह चालू होगा"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ऑडियो शेयर करें"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ऑडियो शेयर किया जा रहा है"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बैटरी"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडियो"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ज़्यादा विजेट जोड़ें"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट पसंद के मुताबिक बनाने के लिए उसे दबाकर रखें"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट अपनी पसंद के मुताबिक बनाएं"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद किए गए विजेट के लिए ऐप्लिकेशन आइकॉन"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इंस्टॉल हो रहे विजेट के लिए ऐप्लिकेशन आइकॉन"</string>
<string name="edit_widget" msgid="9030848101135393954">"विजेट में बदलाव करें"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चुनें"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाएं"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चुने गए विजेट के लिए जगह चुनें"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेन्यू"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सेशन के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं है"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"कोई नई सूचना नहीं है"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"अडैप्टिव नोटिफ़िकेशन चालू हैं"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"अब आपका डिवाइस, तुरंत कई सूचनाएं मिलने पर दो मिनट तक, इनसे होने वाली आवाज़ें कम कर सकता है और स्क्रीन पर कम पॉप-अप दिखा सकता है."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करें"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुरानी सूचाएं देखने के लिए अनलॉक करें"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ज़्यादा जानकारी के लिए टैप करें"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"कोई अलार्म सेट नहीं है"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रीन लॉक डालें"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"फ़िंगरप्रिंट सेंसर को छुएं. यह फ़ोन की साइड में मौजूद एक छोटा बटन होता है"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फ़िंगरप्रिंट सेंसर"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"पुष्टि करें"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिवाइस की होम स्क्रीन पर जाएं"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) पर इस्तेमाल किया जा रहा है"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"हाल ही में, <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ने इस्तेमाल किया"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टम"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टम से जुड़े कंट्रोल"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टम के ऐप्लिकेशन"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"मल्टीटास्किंग (एक साथ कई काम करना)"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रीन"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ऐप शॉर्टकट"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"वापस जाएं"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"वापस जाने के लिए, टचपैड पर कहीं भी तीन उंगलियों से बाईं या दाईं तरफ़ स्वाइप करें."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"टचपैड पर तीन उंगलियों को दाईं और बाईं तरफ़ ले जाया जा रहा है"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"डिवाइस की स्क्रीन पर, पिछले पेज पर जाने के लिए हाथ के जेस्चर का ऐनिमेशन दिख रहा है"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड की बैकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 1eff7d4..372363d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> otkrila je ovu snimku zaslona."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije otkrile su ovu snimku zaslona."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj bilješci"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Snimač zaslona"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavit ćete snimanje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje zaslona"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavit ćete dijeljenje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Emitiranje zaslona"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavit ćete emitiranje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano pomoću lica. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste nastavili."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikacija izvršena"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkaži autentifikaciju"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
@@ -382,11 +385,11 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Snimanje zaslona"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Početak"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavi"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Zabilježi poteškoću"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Zabilježite poteškoću"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Pokreni"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Zaustavi"</string>
- <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Izvješće o pogrešci"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Na koji dio doživljaja na uređaju to utjecalo?"</string>
+ <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Izvješće o programskim pogreškama"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Na koji je dio doživljaja na uređaju to utjecalo?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Odaberite vrstu problema"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Snimanje zaslona"</string>
<string name="performance" msgid="6552785217174378320">"Izvedba"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodavanje još widgeta"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugo pritisnite za prilagodbu widgeta"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi widgete"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za widget koji se instalira"</string>
<string name="edit_widget" msgid="9030848101135393954">"Uredi widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odaberi widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ukloni widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavi odabrani widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Pokreni"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavijesti"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavijesti"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljive obavijesti uklj."</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj sada stišava zvuk i smanjuje broj skočnih prozora na zaslonu na 2 minute kada primite jako puno obavijesti u kratkom vremenskom razdoblju."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte za starije obavijesti"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša je organizacija vlasnik ovog uređaja i može nadzirati mrežni promet"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"unesite zaključavanje zaslona"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dodirnite senzor otiska prsta. To je kraća tipka s bočne strane telefona"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor otiska prsta"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificirali"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pristupili uređaju"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sustav"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrole sustava"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacije sustava"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Obavljanje više zadataka"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podijeljeni zaslon"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečaci aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Natrag"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Za povratak trima prstima prijeđite ulijevo ili udesno bilo gdje na dodirnoj podlozi."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Dodirna podloga prikazuje tri prsta koji se kreću udesno i ulijevo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Na zaslonu uređaja prikazuje se animacija za pokret za povratak"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Upravljanje uređajima"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c0905b5..7c6566f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> észlelte ezt a képernyőképet."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> és más nyitott alkalmazások észlelték ezt a képernyőképet."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Hozzáadás jegyzethez"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Képernyőrögzítő"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
@@ -129,24 +131,25 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Le fogja állítani a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> rögzítését"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <!-- no translation found for share_to_app_chip_accessibility_label (4210256229976947065) -->
+ <skip />
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Le fogja állítani a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> megosztását"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <!-- no translation found for cast_to_other_device_chip_accessibility_label (1680650146639059938) -->
+ <skip />
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Le fogja állítani a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> átküldését"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +198,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Arc felismerve. Koppintson a folytatáshoz."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Arc felismerve. A folytatáshoz koppintson a Feloldásra."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hitelesítés megszakítása"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"További lehetőségek"</string>
@@ -309,10 +314,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Egyes funkciók (például a Quick Share és a Készülékkereső) Bluetootht használnak"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"A Bluetooth holnap reggel bekapcsol"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Hang megosztása"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Hang megosztása…"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hang"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -331,7 +334,7 @@
<string name="quick_settings_user_title" msgid="8673045967216204537">"Felhasználó"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
<string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
- <string name="quick_settings_networks_available" msgid="1875138606855420438">"Használhatók hálózatok"</string>
+ <string name="quick_settings_networks_available" msgid="1875138606855420438">"Elérhető hálózatok"</string>
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Nem használhatók hálózatok"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nincs elérhető Wi-Fi-hálózat"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Bekapcsolás…"</string>
@@ -477,6 +480,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"További modulok hozzáadása"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nyomja meg hosszan a modulok személyre szabásához"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Modulok személyre szabása"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Letiltott modul alkalmazásikonja"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Folyamatban van egy modul alkalmazásikonjának telepítése"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modul szerkesztése"</string>
@@ -495,6 +500,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"modul kiválasztása"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"modul törlése"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kijelölt modul áthelyezése"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"lehúzható menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
@@ -548,6 +559,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nincsenek új értesítések"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Alkalmazkodó értesítések bekapcsolva"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Eszköze most legalább két percre csökkenti a hangerőt és a képernyőn előugró ablakok számát, amikor rövid időn belül sok értesítést kap."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Igen"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"A régebbiek feloldás után láthatók"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Az eszközt a szülőd felügyeli"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Az eszköz az Ön szervezetének tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
@@ -1203,8 +1217,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Koppintással további információkat érhet el."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nincs ébresztés"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"képernyőzár megadása"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Érintse meg az ujjlenyomat-érzékelőt. Ez a rövidebb gomb a telefon oldalán."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Ujjlenyomat-érzékelő"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"a hitelesítéshez"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"eszköz megadásához"</string>
@@ -1346,7 +1359,15 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Használatban a következő által: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Legutóbb használta: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Rendszer"</string>
+ <!-- no translation found for shortcut_helper_category_system_controls (3153344561395751020) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_category_system_apps (6001757545472556810) -->
+ <skip />
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <!-- no translation found for shortcutHelper_category_recent_apps (7918731953612377145) -->
+ <skip />
+ <!-- no translation found for shortcutHelper_category_split_screen (1159669813444812244) -->
+ <skip />
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Bevitel"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Alkalmazás-parancsikonok"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
@@ -1363,6 +1384,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Vissza"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"A visszalépéshez csúsztasson három ujjal gyorsan balra vagy a jobbra az érintőpad tetszőleges területén."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Három, jobbra és balra mozgó ujjat ábrázoló érintőpad"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"A Vissza kézmozdulat animációját megjelenítő eszközképernyő"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"A billentyűzet háttérvilágítása"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Fényerő: %2$d/%1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Otthon vezérlése"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 41593d8..b00328a 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը հայտնաբերել է այս սքրինշոթը։"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-ն ու բացված այլ հավելվածներ հայտնաբերել են այս սքրինշոթը։"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ավելացնել նշմանը"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Էկրանի տեսագրում"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Դուք կկանգնեցնեք <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածից բովանդակության տեսագրումը"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Միացված է էկրանի ցուցադրումը"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Դուք կկանգնեցնեք <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածից բովանդակության փոխանցումը"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Էկրանի հեռարձակում"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Դուք կկանգնեցնեք <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածից բովանդակության հեռարձակումը"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ապակողպվել է դեմքով։ Սեղմեք շարունակելու համար։"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Դեմքը ճանաչվեց։ Սեղմեք շարունակելու համար։"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Դեմքը ճանաչվեց։ Սեղմեք ապակողպման պատկերակը։"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Նույնականացված է"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Չեղարկել իսկորոշումը"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Լրացուցիչ ընտրանքներ"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth-ն օգտագործում են, օրինակ, Quick Share և «Գտնել իմ սարքը» գործառույթները"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth-ը կմիանա վաղն առավոտյան"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Փոխանցել աուդիո"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Աուդիոյի փոխանցում"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Աուդիո"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ականջակալ"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ավելացնել վիջեթներ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Երկար սեղմեք՝ վիջեթները հարմարեցնելու համար"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Հարմարեցնել վիջեթները"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Հավելվածի պատկերակ անջատված վիջեթի համար"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Տեղադրվող վիջեթի հավելվածի պատկերակ"</string>
<string name="edit_widget" msgid="9030848101135393954">"Փոփոխել վիջեթը"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ընտրել վիջեթ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"հեռացնել վիջեթը"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"տեղադրել ընտրված վիջեթը"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"իջնող ընտրացանկ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ծանուցումներ չկան"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Նոր ծանուցումներ չկան"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Հարմարվող ծանուցումները միացված են"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Եթե կարճ ժամանակամիջոցում շատ ծանուցումներ ստանաք, ձայնը և ելնող պատուհանների թիվը կնվազեցվի մինչև երկու րոպեով։"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Անջատել"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ապակողպեք՝ տեսնելու հին ծանուցումները"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Այս սարքը կառավարում է ձեր ծնողը"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ձեր կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Հպեք՝ ավելին իմանալու համար"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Զարթուցիչ դրված չէ"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ապակողպել էկրանը"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Հպեք մատնահետքի սկաներին։ Այն հեռախոսի կողքի ավելի կարճ կոճակն է"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Մատնահետքի սկաներ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"նույնականացնել"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"նշել սարքը"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Օգտագործվում է <xliff:g id="APP_NAME">%1$s</xliff:g>ի կողմից (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Վերջերս օգտագործվել է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի կողմից (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Համակարգ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Համակարգի կառավարման տարրեր"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Համակարգային հավելվածներ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմախնդրություն"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Վերջին օգտագործած հավելվածները"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Տրոհված էկրան"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ներածում"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Հավելվածի դյուրանցումներ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Հետ գնալ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Հետ գնալու համար հպահարթակի վրա երեք մատով սահեցրեք ձախ կամ աջ։"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Երեք մատները աջ ու ձախ են շարժվում հպահարթակի վրա"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Սարքի էկրանին ցուցադրվում է շարժանկար՝ հետ գնալու ժեստի համար"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Հետին լուսավորությամբ ստեղնաշար"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d՝ %2$d-ից"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Տան կառավարման տարրեր"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 831adf9..b235236 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> mendeteksi screenshot ini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan aplikasi terbuka lainnya mendeteksi screenshot ini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan ke catatan"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Perekam Layar"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Anda akan berhenti merekam <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Membagikan layar"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Anda akan berhenti membagikan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Mentransmisikan layar"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Anda akan berhenti mentransmisikan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Kunci dibuka dengan wajah. Tekan untuk melanjutkan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dikenali. Tekan untuk melanjutkan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dikenali. Tekan ikon buka kunci untuk melanjutkan."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Autentikasi"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsi Lainnya"</string>
@@ -386,7 +389,7 @@
<string name="qs_record_issue_start" msgid="2979831312582567056">"Mulai"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Berhenti"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Laporan Bug"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Bagian pengalaman perangkat mana yang terpengaruh?"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Hal apa yang terpengaruh?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Pilih jenis masalah"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Perekaman layar"</string>
<string name="performance" msgid="6552785217174378320">"Performa"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan widget lainnya"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon aplikasi untuk widget yang dinonaktifkan"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikon aplikasi untuk widget yang sedang diinstal"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pilih widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"hapus widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"letakkan widget yang dipilih"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pulldown"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data dalam sesi ini akan dihapus."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Tidak ada notifikasi"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Tidak ada notifikasi baru"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifikasi adaptif aktif"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Perangkat Anda kini akan menurunkan volume dan mengurangi jendela pop-up di layar hingga dua menit saat Anda menerima banyak notifikasi dalam waktu singkat."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Nonaktifkan"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat notifikasi lama"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Perangkat ini dikelola oleh orang tuamu"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi Anda memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketuk untuk informasi selengkapnya"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm tidak disetel"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"masukkan kunci layar"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Sentuh sensor sidik jari. Sensor terletak di tombol yang lebih pendek di samping layar ponsel"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor sidik jari"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentikasi"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"masukkan perangkat"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Sedang digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Baru saja digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrol sistem"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikasi sistem"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplikasi terbaru"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Layar terpisah"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Pintasan aplikasi"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Untuk kembali, geser ke kiri atau ke kanan menggunakan tiga jari ke mana saja di touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad menampilkan tiga jari yang bergerak ke kanan dan ke kiri"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Layar perangkat menampilkan animasi untuk gestur kembali"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Lampu latar keyboard"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrol Rumah"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index a73bd7a..ff5f3b8 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> greindi skjámyndina."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og önnur opin forrit greindu skjámyndina."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Bæta við glósu"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Skjáupptaka"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Þú munt hætta upptöku úr <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deilir skjá"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Þú munt hætta að deila úr <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Varpar skjá"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Þú munt hætta vörpun úr <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Opnað með andliti. Ýttu til að halda áfram."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Andlitið var greint. Ýttu til að halda áfram."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Andlitið var greint. Ýttu á opnunartáknið til að halda áfr."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hætta við auðkenningu"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fleiri valkostir"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Bæta við fleiri græjum"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Haltu inni til að sérsníða græjur"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sérsníða græjur"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Forritstákn fyrir græju sem slökkt er á"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Forritatákn fyrir græju sem verið er að setja upp"</string>
<string name="edit_widget" msgid="9030848101135393954">"Breyta græju"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velja græju"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjarlægja græju"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"koma valinni græju fyrir"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Fellivalmynd"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Engar tilkynningar"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Engar nýjar tilkynningar"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Kveikt er á breytilegum tilkynningum"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tækið þitt lækkar nú hljóðstyrkinn og fækkar sprettigluggum á skjánum í allt að tvær mínútur þegar þú færð margar tilkynningar á stuttum tíma."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slökkva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Taktu úr lás til að sjá eldri tilkynningar"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Foreldri þitt stjórnar þessu tæki"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Fyrirtækið þitt á þetta tæki og fylgist hugsanlega með netumferð"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ýttu til að fá frekari upplýsingar"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Enginn vekjari"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"sláðu inn skjálás"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Snertu fingrafaralesarann. Það er styttri hnappurinn á hlið símans"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingrafaralesari"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"auðkenna"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"opna tæki"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Í notkun í <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nýlega notað af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Kerfi"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kerfisstýringar"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Kerfisforrit"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Fjölvinnsla"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nýleg forrit"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Skjáskipting"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inntak"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Flýtileiðir forrita"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Til baka"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Strjúktu til vinstri eða hægri með þrem fingrum hvar sem er á snertifletinum til að fara til baka."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Snertiflötur sem sýnir þrjá fingur færast til hægri og vinstri"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Skjár tækis sem sýnir hreyfimynd fyrir bendinguna „til baka“."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Baklýsing lyklaborðs"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Stig %1$d af %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Heimastýringar"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index a424f20..90d55f7 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha rilevato questo screenshot."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e altre app aperte hanno rilevato questo screenshot."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Aggiungi alla nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Includi link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Registrazione dello schermo"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaborazione registrazione…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Interromperai la registrazione di <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Condivisione dello schermo in corso"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Interromperai la condivisione di <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Trasmissione dello schermo attiva"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Interromperai la trasmissione di <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Sbloccato con il volto. Premi per continuare."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Volto riconosciuto. Premi per continuare."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Volto riconosciuto. Premi l\'icona Sblocca e continua."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Sbloccato con il volto. Tocca per continuare."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annulla autenticazione"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Altre opzioni"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Aggiungi altri widget"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Premi a lungo per personalizzare i widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizza widget"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona dell\'app per widget disattivati"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona dell\'app per un widget in fase di installazione"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifica widget"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleziona widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"rimuovi widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posiziona il widget selezionato"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu a discesa"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nessuna nuova notifica"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifiche adattive attivate"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Il dispositivo abbassa il volume e riduce i popup fino a 2 minuti quando ricevi molte notifiche."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Disattiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Sblocca per vedere le notifiche meno recenti"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Questo dispositivo è gestito dai tuoi genitori"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Questo dispositivo appartiene alla tua organizzazione, che potrebbe monitorare il traffico di rete"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tocca per ulteriori informazioni"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nessuna"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"inserisci blocco schermo"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Tocca il sensore di impronte digitali. È il tasto più corto sul lato dello smartphone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensore di impronte digitali"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"effettuare l\'autenticazione"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accedere al dispositivo"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In uso da <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recentemente in uso da <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controlli di sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"App di sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"App recenti"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Schermo diviso"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Scorciatoie app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Indietro"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Per tornare indietro, scorri verso sinistra o verso destra utilizzando tre dita in un punto qualsiasi del touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad che mostra tre dita che si muovono verso destra e sinistra"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Schermata del dispositivo che mostra l\'animazione del gesto per tornare indietro"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroilluminazione della tastiera"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Livello %1$d di %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controlli della casa"</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index aa76983..2fd4f6d 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -188,7 +188,7 @@
</string-array>
<string-array name="tile_states_hearing_devices">
<item msgid="1235334096484287173">"Non disponibile"</item>
- <item msgid="3079622119444911877">"Off"</item>
- <item msgid="3028994095749238254">"On"</item>
+ <item msgid="3079622119444911877">"Disattivi"</item>
+ <item msgid="3028994095749238254">"Attivi"</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 4e0977e..c594080 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -103,11 +103,12 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> זיהתה את צילום המסך הזה."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> ואפליקציות פתוחות נוספות זיהו את צילום המסך הזה."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"הוספה לפתק"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"הכנסת הקישור"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"מקליט המסך"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"להתחיל את ההקלטה?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"בזמן ההקלטה, תהיה ל-Android גישה לכל מה שמופיע במסך שלך או מנוגן במכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"בזמן ההקלטה, תהיה ל-Android גישה לכל מה שמופיע במסך שלך או מופעל במכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"בזמן הקלטה של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"התחלת ההקלטה"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"הקלטת אודיו"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ההקלטה של <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> תיפסק"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"שיתוף המסך מתבצע"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"השיתוף של <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> יופסק"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"הפעלת Cast של המסך מתבצעת"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"הפעלת ה-Cast של <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> תיפסק"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי להמשיך."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"הפנים זוהו. יש ללחוץ כדי להמשיך."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך להקיש כדי להמשיך."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ביטול האימות"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"אפשרויות נוספות"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"תכונות כמו \'שיתוף מהיר\' ו\'איפה המכשיר שלי\' משתמשות ב-Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"חיבור ה-Bluetooth יופעל מחר בבוקר"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"שיתוף האודיו"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"מתבצע שיתוף של האודיו"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> סוללה"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"אודיו"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"אוזניות"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"הוספת ווידג\'טים"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"לוחצים לחיצה ארוכה כדי להתאים אישית את הווידג\'טים"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"התאמה אישית של ווידג\'טים"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"סמל האפליקציה לווידג\'ט שהושבת"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"סמל האפליקציה של ווידג\'ט בתהליך התקנה"</string>
<string name="edit_widget" msgid="9030848101135393954">"עריכת הווידג\'ט"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"צריך לבחור ווידג\'ט"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"הסרת הווידג\'ט"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"צריך למקם את הווידג\'ט שנבחר"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"תפריט במשיכה למטה"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"אין התראות חדשות"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ההתראות המותאמות מופעלות"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"מעכשיו, כשיש התראות רבות בזמן קצר, עוצמת הקול מופחתת ומופיעים פחות חלונות קופצים במשך עד שתי דקות."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"השבתה"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"יש לבטל את הנעילה כדי לראות התראות ישנות"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"המכשיר הזה מנוהל על ידי ההורה שלך"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"הארגון שלך הוא הבעלים של המכשיר הזה והוא עשוי לנטר את התנועה ברשת"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"לא הוגדרה"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"הזנת קוד נעילת המסך"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"צריך לגעת בחיישן טביעות האצבע. זה הלחצן הקצר יותר בצד של הטלפון"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"חיישן טביעות אצבע"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"אימות"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"הזנת מכשיר"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"בשימוש על ידי <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"נעשה שימוש לאחרונה על ידי <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"מערכת"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"הגדרות המערכת"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"אפליקציות מערכת"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ריבוי משימות"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"אפליקציות אחרונות"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"מסך מפוצל"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"קלט"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"קיצורי דרך של אפליקציות"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"חזרה"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"כדי לחזור אחורה, מחליקים שמאלה או ימינה עם שלוש אצבעות בכל מקום על לוח המגע."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"לוח מגע שמראה שלוש אצבעות זזות ימינה ושמאלה"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"מסך מכשיר שמראה אנימציה לתנועה אחורה"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"רמה %1$d מתוך %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"שליטה במכשירים"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 6c8504bb..da35701 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> がこのスクリーンショットを検出しました。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> とその他の開いているアプリがこのスクリーンショットを検出しました。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"メモに追加"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"リンクを含める"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"スクリーン レコーダー"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> の記録を停止します"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"画面を共有しています"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> の共有を停止します"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"画面をキャストしています"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> のキャストを停止します"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"顔でロック解除しました。押して続行してください。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"顔を認識しました。押して続行してください。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"顔を認識しました。ロック解除アイコンを押して続行します。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"顔認証でロック解除しました。タップして続行します。"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"認証をキャンセルします"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"その他のオプション"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share や「デバイスを探す」などの機能は Bluetooth を使用します"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"明日の朝に Bluetooth が ON になります"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"音声を共有"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"音声を共有中"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"オーディオ"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ヘッドセット"</string>
@@ -389,7 +388,7 @@
<string name="qs_record_issue_stop" msgid="3531747965741982657">"停止"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"バグレポート"</string>
<string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"デバイスのどの部分が影響を受けましたか?"</string>
- <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"問題の種類を選択する"</string>
+ <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"問題の種類を選択"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"スクリーン レコード"</string>
<string name="performance" msgid="6552785217174378320">"パフォーマンス"</string>
<string name="user_interface" msgid="3712869377953950887">"ユーザー インターフェース"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ウィジェットの追加"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長押ししてウィジェットをカスタマイズ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ウィジェットのカスタマイズ"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"無効なウィジェットのアプリアイコン"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"インストール中のウィジェットのアプリアイコン"</string>
<string name="edit_widget" msgid="9030848101135393954">"ウィジェットを編集"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ウィジェットを選択"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ウィジェットを削除"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"選択したウィジェットを配置"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"プルダウン メニュー"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"今すぐ開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"通知はありません"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"新しい通知はありません"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"通知の自動調整は ON です"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"短期間に多くの通知が届いたときに最長 2 分間デバイスの音量を下げて画面上のポップアップを減らします。"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"OFF にする"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ロック解除して以前の通知を表示"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"このデバイスは保護者によって管理されています"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"これは組織が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"タップすると詳細が表示されます"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"アラーム未設定"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"画面ロックを設定"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"指紋認証センサーに触れてください。スマートフォンの側面にある高さが低い方のボタンです。"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指紋認証センサー"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"認証"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"デバイスを入力"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> が使用中(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> が最近使用(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"システム"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"システム コントロール"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"システムアプリ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"マルチタスク"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使ったアプリ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割画面"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"入力"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"アプリのショートカット"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"戻る"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"戻るには、3 本の指でタッチパッドを左右にスワイプします。"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"タッチパッドで 3 本の指を左右に動かしている様子"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"デバイスの画面で「戻る」ジェスチャーのアニメーションが表示されている様子"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"キーボード バックライト"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ホーム コントロール"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index c21dc10..977fed7 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა აღმოაჩინა ეკრანის ეს ანაბეჭდი"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა და სხვა გახსნილმა აპებმა აღმოაჩინეს ეკრანის ეს ანაბეჭდი."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"დაამატეთ შენიშვნა"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ბმულის დართვა"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ეკრანის ჩამწერი"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ეკრანის ჩანაწერი მუშავდება"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"თქვენ შეწყვეტთ <b><xliff:g id="APP_NAME">%1$s</xliff:g>-ის</b> ჩაწერას"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"მიმდინარეობს ეკრანის გაზიარება"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"თქვენ შეწყვეტთ <b><xliff:g id="APP_NAME">%1$s</xliff:g>-ის</b> გაზიარებას"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"მიმდინარეობს ეკრანის ტრანსლირება"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"თქვენ შეწყვეტთ <b><xliff:g id="APP_NAME">%1$s</xliff:g>-ის</b> ტრანსლირებას"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"განიბლოკა სახით. დააჭირეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ამოცნობილია სახით. დააჭირეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ამოცნობილია სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"განიბლოკა სახით. შეეხეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ავტორიზებულია"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ავტორიზაციის გაუქმება"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"სხვა ვარიანტები"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ისეთი ფუნქციები, როგორიცაა სწრაფი გაზიარება და ჩემი მოწყობილობის პოვნა, იყენებს Bluetooth-ს"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ჩაირთვება ხვალ დილით"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"აუდიოს გაზიარება"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"მიმდინარებოს აუდიოს გაზიარება"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ბატარეა"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"აუდიო"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ყურსაცვამი"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ვიჯეტების დამატება"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ხანგრძლივად დააჭირეთ ვიჯეტების მოსარგებად"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ვიჯეტების მორგება"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"აპის ხატულა გათიშული ვიჯეტისთვის"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ინსტალაციის პროცესში მყოფი ვიჯეტის აპის ხატულა"</string>
<string name="edit_widget" msgid="9030848101135393954">"ვიჯეტის რედაქტირება"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ვიჯეტის არჩევა"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ვიჯეტის ამოშლა"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"არჩეული ვიჯეტის განთავსება"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ჩამოშლადი მენიუ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"დაწყება ახლავე"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"შეტყობინებები არ არის."</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ახალი შეტყობინებები არ არის"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"მორგებადი შეტყობინებები ჩართულია"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"მოკლე დროში ბევრი შეტყობინების მიღებისას თქვენი მოწყობილობა ახლა უკვე ამცირებს ხმას და ეკრანზე ამომხტარი ფანჯრების რაოდენობას."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"გამორთვა"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"განბლოკეთ ძველი შეტყობინებების სანახავად"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"მოწყობილობას თქვენი მშობელი მართავს"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"შეეხეთ მეტი ინფორმაციისთვის"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"მაღვიძარა არ არის"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ეკრანის დაბლოკვის შეყვანა"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"შეეხეთ თითის ანაბეჭდის სენსორს. ის მოკლე ღილაკია ტელეფონის კიდეზე"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"თითის ანაბეჭდის სენსორი"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ავტორიზაცია"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"მოწყობილობის შეყვანა"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"გამოიყენება <xliff:g id="APP_NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ახლახან გამოყენებულია <xliff:g id="APP_NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"სისტემა"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"სისტემის მართვის საშუალებები"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"სისტემის აპები"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"მრავალამოცანიანი რეჟიმი"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ბოლოდროინდელი აპები"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ეკრანის გაყოფა"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"შეყვანა"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"აპის მალსახმობები"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"უკან დაბრუნება"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"უკან დასაბრუნებლად, სენსორულ პანელზე ნებისმიერ ადგილას სამი თითის გამოყენებით გადაფურცლეთ მარცხნივ ან მარჯვნივ."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"სენსორული პანელი, რომელიც აჩვენებს მარჯვენა და მარცხენა მიმართულებით მოძრავ სამ თითს"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"მოწყობილობის ეკრანი, რომელიც აჩვენებს უკან დაბრუნების ჟესტის ანიმაციას"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"კლავიატურის შენათება"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"დონე: %1$d %2$d-დან"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"სახლის კონტროლი"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 0a7b976..3df7fc1 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -103,11 +103,13 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасы осы скриншотты анықтады."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> және басқа да ашық қолданбалар осы скриншотты анықтады."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ескертпеге қосу"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Экран жазғыш"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Жазу басталсын ба?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Жазу кезінде Android жүйесі экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Жазу кезінде Android жүйесі экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерге, төлем туралы мәліметке, хабарларға, фотосуреттерге, аудиоконтент пен бейнелерге сақ болыңыз."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Қолданбаны жазу кезінде Android жүйесі қолданбада көрінетін не ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Жазуды бастау"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жазу"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасының контентін жазуды тоқтатасыз."</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экранды бөлісіп жатыр."</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасының контентін бөлісуді тоқтатасыз."</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Экранды трансляциялап жатыр."</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасының контентін трансляциялауды тоқтатасыз."</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Бетпен ашылды. Жалғастыру үшін басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Бет танылды. Жалғастыру үшін басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Бет танылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аутентификациядан бас тарту"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Қосымша опциялар"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share және Find My Device сияқты функциялар Bluetooth-ты пайдаланады."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ертең таңертең қосылады."</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Аудионы бөлісу"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Аудио бөлісіліп жатыр"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Aудио"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string>
@@ -389,9 +390,9 @@
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Тоқтату"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Қате туралы есеп"</string>
<string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Құрылғы қызметінің қандай түріне әсер етті?"</string>
- <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Мәселе түрін таңдаңыз."</string>
+ <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Ақау түрін таңдаңыз"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Экранды жазу"</string>
- <string name="performance" msgid="6552785217174378320">"Өнімділік режимі"</string>
+ <string name="performance" msgid="6552785217174378320">"Өнімділік"</string>
<string name="user_interface" msgid="3712869377953950887">"Пайдаланушы интерфейсі"</string>
<string name="thermal" msgid="6758074791325414831">"Термовизия"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Бір қолмен басқару режимі"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Басқа виджеттер қосыңыз."</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерді бейімдеу үшін ұзақ басып тұрыңыз."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерді реттеу"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өшірілген виджеттің қолданба белгішесі"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджетке арналған қолдана белгішесі орнатылып жатыр."</string>
<string name="edit_widget" msgid="9030848101135393954">"Виджетті өзгерту"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет таңдау"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетті өшіру"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"таңдалған виджетті орналастыру"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданба мен дерек жойылады."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Хабарландырулар жоқ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңа хабарландырулар жоқ"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Бейімделетін хабарландырулар қосулы"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Қысқа уақыт аралығында көп хабарландыру алсаңыз, құрылғыңыз дыбыс деңгейін және экранда шығатын қалқымалы терезелердің уақытын екі минутқа дейін азайтады."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өшіру"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ескі хабарландырулар үшін құлыпты ашыңыз"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бұл құрылғыны ата-анаңыз басқарады."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Толығырақ ақпарат алу үшін түртіңіз."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Оятқыш орнатылмаған."</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"экран құлпын енгізу"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Саусақ ізін оқу сканерін түртіңіз. Ол – телефонның бүйіріндегі шағын түйме."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Саусақ ізін оқу сканері"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"аутентификациялау"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"құрылғыны енгізу"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) қолданбасы пайдаланып жатыр"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Соңғы рет <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) қолданбасы пайдаланды."</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Жүйе"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Жүйені басқару элементтері"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Жүйелік қолданбалар"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Мультитаскинг"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Соңғы қолданбалар"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Экранды бөлу"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Кіріс"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Қолданба таңбашалары"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артқа"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Артқа қайту үшін сенсорлық тақтаның кез келген жерінен үш саусақпен солға немесе оңға сырғытыңыз."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Оңға және солға жылжитын үш саусақты көрсетіп тұрған сенсорлық тақта."</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Артқа қайту қимылын көрсетіп тұрған құрылғы экраны."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Пернетақта жарығы"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Деңгей: %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Үй басқару элементтері"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 20a9ae5..303410d 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> បានរកឃើញរូបថតអេក្រង់នេះ។"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> និងកម្មវិធីដែលបើកផ្សេងទៀតបានរកឃើញរូបថតអេក្រង់នេះ។"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"បញ្ចូលទៅក្នុងកំណត់ចំណាំ"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"មុខងារថតវីដេអូអេក្រង់"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុងដំណើរការការថតអេក្រង់"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹងដែលកំពុងដំណើរការសម្រាប់រយៈពេលប្រើការថតសកម្មភាពអេក្រង់"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"អ្នកនឹងឈប់ថត <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"កំពុងបង្ហាញអេក្រង់"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"អ្នកនឹងឈប់ចែករំលែក <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"កំពុងបញ្ជូនអេក្រង់"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"អ្នកនឹងឈប់បញ្ជូន <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបន្ត។"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបន្ត។"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បានផ្ទៀងផ្ទាត់"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"បោះបង់ការផ្ទៀងផ្ទាត់"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ជម្រើសច្រើនទៀត"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"មុខងារដូចជា Quick Share និង \"រកឧបករណ៍របស់ខ្ញុំ\" ប្រើប៊្លូធូស"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ប៊្លូធូសនឹងបើកនៅព្រឹកស្អែក"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ស្ដាប់សំឡេងរួមគ្នា"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"កំពុងស្ដាប់សំឡេងរួមគ្នា"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"សំឡេង"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"កាស"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"បញ្ចូលធាតុក្រាហ្វិកច្រើនទៀត"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ចុចឱ្យយូរ ដើម្បីប្ដូរធាតុក្រាហ្វិកតាមបំណង"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ប្ដូរធាតុក្រាហ្វិកតាមបំណង"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"រូបកម្មវិធីសម្រាប់ធាតុក្រាហ្វិកដែលបានបិទ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"រូបតំណាងកម្មវិធីសម្រាប់ធាតុក្រាហ្វិកកំពុងត្រូវបានដំឡើង"</string>
<string name="edit_widget" msgid="9030848101135393954">"កែធាតុក្រាហ្វិក"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ជ្រើសរើសធាតុក្រាហ្វិក"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ដកធាតុក្រាហ្វិកចេញ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ដាក់ធាតុក្រាហ្វិកដែលបានជ្រើសរើស"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរអ្នកប្រើ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ម៉ឺនុយទាញចុះ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យទាំងអស់ក្នុងវគ្គនេះនឹងត្រូវលុប។"</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ចាប់ផ្ដើមឥឡូវ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"គ្មានការជូនដំណឹង"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"គ្មានការជូនដំណឹងថ្មីៗទេ"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ការជូនដំណឹងដែលបត់បែនត្រូវបានបើក"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ឥឡូវនេះ ឧបករណ៍របស់អ្នកបន្ថយកម្រិតសំឡេង និងកាត់បន្ថយផ្ទាំងលោតឡើងនៅលើអេក្រង់រយៈពេលរហូតដល់ពីរនាទី នៅពេលអ្នកទទួលបានការជូនដំណឹងច្រើនក្នុងរយៈពេលខ្លី។"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"បិទ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ដោះសោដើម្បីមើលការជូនដំណឹងចាស់ៗ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ឧបករណ៍នេះស្ថិតក្រោមការគ្រប់គ្រងរបស់មាតាបិតាអ្នក"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ស្ថាប័នរបស់អ្នកជាម្ចាស់ឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ចុចដើម្បីទទួលបានព័ត៌មានបន្ថែម"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"មិនបានកំណត់ម៉ោងរោទ៍ទេ"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"បញ្ចូលព័ត៌មានផ្ទៀងផ្ទាត់សម្រាប់ការចាក់សោអេក្រង់"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ប៉ះសេនស័រចាប់ស្នាមម្រាមដៃ។ វាជាប៊ូតុងខ្លីនៅចំហៀងទូរសព្ទ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ឧបករណ៍ចាប់ស្នាមម្រាមដៃ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ផ្ទៀងផ្ទាត់"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"បញ្ចូលឧបករណ៍"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"កំពុងប្រើដោយ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"បានប្រើនាពេលថ្មីៗនេះដោយ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ប្រព័ន្ធ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ការគ្រប់គ្រងប្រព័ន្ធ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"កម្មវិធីប្រព័ន្ធ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ការដំណើរការបានច្រើន"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"កម្មវិធីថ្មីៗ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"មុខងារបំបែកអេក្រង់"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ធាតុចូល"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ផ្លូវកាត់កម្មវិធី"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ថយក្រោយ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ដើម្បីថយក្រោយ សូមអូសទៅឆ្វេង ឬស្ដាំដោយប្រើម្រាមដៃបីនៅកន្លែងណាមួយនៅលើផ្ទាំងប៉ះ។"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ផ្ទាំងប៉ះដែលបង្ហាញម្រាមដៃបីដែលផ្លាស់ទីទៅស្ដាំ និងឆ្វេង"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"អេក្រង់ឧបករណ៍ដែលបង្ហាញរូបមានចលនាសម្រាប់ចលនាថយក្រោយ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ពន្លឺក្រោយក្ដារចុច"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"កម្រិតទី %1$d នៃ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ការគ្រប់គ្រងផ្ទះ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 922075a..4af252d 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"ಈ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು <xliff:g id="APPNAME">%1$s</xliff:g> ಪತ್ತೆಹಚ್ಚಿದೆ."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ಹಾಗೂ ತೆರೆದಿರುವ ಇತರ ಆ್ಯಪ್ಗಳು ಈ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಪತ್ತೆಹಚ್ಚಿವೆ."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ಟಿಪ್ಪಣಿಗೆ ಸೇರಿಸಿ"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"ಲಿಂಕ್ ಅನ್ನು ಸೇರಿಸಿ"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ಇದರಿಂದ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ನ ಕಂಟೆಂಟ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ಪರದೆಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ಇದರಿಂದ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ನ ಕಂಟೆಂಟ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ಪರದೆಯನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ಇದರಿಂದ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ನ ಕಂಟೆಂಟ್ ಅನ್ನು ಬಿತ್ತರಿಸುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ದೃಢೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ಕ್ವಿಕ್ ಶೇರ್ ಮತ್ತು Find My Device ನಂತಹ ಫೀಚರ್ಗಳು ಬ್ಲೂಟೂತ್ ಅನ್ನು ಬಳಸುತ್ತವೆ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ಬ್ಲೂಟೂತ್ ನಾಳೆ ಬೆಳಗ್ಗೆ ಆನ್ ಆಗುತ್ತದೆ"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ಆಡಿಯೋವನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ಆಡಿಯೋ"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ಹೆಡ್ಸೆಟ್"</string>
@@ -388,7 +387,7 @@
<string name="qs_record_issue_start" msgid="2979831312582567056">"ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"ನಿಲ್ಲಿಸಿ"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"ಬಗ್ ವರದಿ ಮಾಡುವಿಕೆ"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"ಸಾಧನ ಬಳಸುವಾಗ ನೀವು ಯಾವ ರೀತಿಯ ಸಮಸ್ಯೆ ಎದುರಿಸುತ್ತೀರಿ?"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"ನಿಮ್ಮ ಸಾಧನದ ಯಾವ ಭಾಗದಲ್ಲಿ ಸಮಸ್ಯೆ ಉಂಟಾಗಿದೆ?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"ಸಮಸ್ಯೆಯ ಪ್ರಕಾರವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡ್"</string>
<string name="performance" msgid="6552785217174378320">"ಪರ್ಫಾರ್ಮೆನ್ಸ್"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ಹೆಚ್ಚಿನ ವಿಜೆಟ್ಗಳನ್ನು ಸೇರಿಸಿ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ವಿಜೆಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ದೀರ್ಘಕಾಲ ಒತ್ತಿರಿ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ವಿಜೆಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾದ ವಿಜೆಟ್ಗಾಗಿ ಆ್ಯಪ್ ಐಕಾನ್"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾದ ವಿಜೆಟ್ಗಾಗಿ ಆ್ಯಪ್ ಐಕಾನ್"</string>
<string name="edit_widget" msgid="9030848101135393954">"ವಿಜೆಟ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ವಿಜೆಟ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ವಿಜೆಟ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ಆಯ್ಕೆಮಾಡಿದ ವಿಜೆಟ್ ಅನ್ನು ಇರಿಸಿ"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ಪುಲ್ಡೌನ್ ಮೆನು"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಶನ್ನಲ್ಲಿನ ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ಯಾವುದೇ ಹೊಸ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ಅಡಾಪ್ಟಿವ್ ನೋಟಿಫಿಕೇಶನ್ ಆನ್ ಇದೆ"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ಅಲ್ಪಾವಧಿಯಲ್ಲಿ ಹಲವು ನೋಟಿಫಿಕೇಶನ್ ಬಂದಾಗ 2 ನಿಮಿಷದವರೆಗೆ ಸಾಧನವು ಈಗ ವಾಲ್ಯೂಮ್ ಕಡಿಮೆ ಮಾಡುತ್ತದೆ ಹಾಗೂ ಸ್ಕ್ರೀನ್ ಮೇಲಿನ ಪಾಪ್-ಅಪ್ ಕಡಿಮೆ ಮಾಡುತ್ತದೆ."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ಆಫ್ ಮಾಡಿ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ಹಳೆಯ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಲು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ಅಲಾರಾಂ ಸೆಟ್ ಆಗಿಲ್ಲ"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ನಮೂದಿಸಿ"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ. ಇದು ಫೋನ್ನ ಬದಿಯಲ್ಲಿರುವ ಚಿಕ್ಕ ಬಟನ್ ಆಗಿದೆ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ದೃಢೀಕರಿಸಿ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ಸಾಧನವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನಿಂದ ಬಳಕೆಯಲ್ಲಿದೆ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ಇತ್ತೀಚೆಗೆ <xliff:g id="APP_NAME">%1$s</xliff:g> ಇದನ್ನು ಬಳಸಿದೆ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ಸಿಸ್ಟಂ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ಸಿಸ್ಟಂ ನಿಯಂತ್ರಣಗಳು"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ಸಿಸ್ಟಂ ಆ್ಯಪ್ಗಳು"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ಮಲ್ಟಿಟಾಸ್ಕಿಂಗ್"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್ಗಳು"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ಇನ್ಪುಟ್"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ಆ್ಯಪ್ ಶಾರ್ಟ್ಕಟ್ಗಳು"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ಹಿಂತಿರುಗಿ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ಹಿಂತಿರುಗಲು, ಟಚ್ಪ್ಯಾಡ್ನಲ್ಲಿ ಎಲ್ಲಿಯಾದರೂ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಎಡ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ಮೂರು ಬೆರಳುಗಳು ಬಲಕ್ಕೆ ಮತ್ತು ಎಡಕ್ಕೆ ಚಲಿಸುತ್ತಿರುವುದನ್ನು ತೋರಿಸುತ್ತಿರುವ ಟಚ್ಪ್ಯಾಡ್"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ಗೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯನಿಮೇಶನ್ ಅನ್ನು ತೋರಿಸುತ್ತಿರುವ ಸಾಧನದ ಸ್ಕ್ರೀನ್"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್ಲೈಟ್"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ಮನೆ ನಿಯಂತ್ರಣಗಳು"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 496307a..dc1ebf1 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>에서 이 스크린샷을 감지했습니다."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 및 기타 공개 앱에서 이 스크린샷을 감지했습니다."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"메모에 추가"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"화면 녹화"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 녹화가 중단됩니다."</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"화면 공유 중"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 공유가 중단됩니다."</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"화면 전송 중"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 전송이 중단됩니다."</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 누르세요."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"얼굴이 인식되었습니다. 계속하려면 누르세요."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"얼굴이 인식되었습니다. 계속하려면 아이콘을 누르세요."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"인증 취소"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"옵션 더보기"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, 내 기기 찾기 등의 기능에서 블루투스를 사용합니다."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"블루투스가 내일 아침에 켜집니다."</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"오디오 공유"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"오디오 공유 중"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"오디오"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"헤드셋"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"더 많은 위젯 추가"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"위젯을 맞춤설정하려면 길게 누르기"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"위젯 맞춤설정"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"사용 중지된 위젯의 앱 아이콘"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"설치 중인 위젯의 앱 아이콘"</string>
<string name="edit_widget" msgid="9030848101135393954">"위젯 수정"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"위젯 선택"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"위젯 삭제"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"선택한 위젯 배치"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"풀다운 메뉴"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"새로운 알림 없음"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"적응형 알림 사용 중"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"이제 짧은 시간 동안 많은 알림을 받으면 최대 2분 동안 기기의 볼륨을 낮추고 화면의 팝업을 줄입니다."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"사용 중지"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"잠금 해제하여 이전 알림 보기"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"부모님이 관리하는 기기입니다."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"내 조직에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"탭하여 자세한 정보를 확인하세요."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"설정된 알람 없음"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"화면 잠금 입력"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"지문 센서를 터치하세요. 휴대전화 측면에 있는 더 짧은 버튼입니다"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"지문 센서"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"인증"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"기기 입력"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 사용 중(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"최근 <xliff:g id="APP_NAME">%1$s</xliff:g>에서 사용됨(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"시스템"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"시스템 컨트롤"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"시스템 앱"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"멀티태스킹"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"최근 앱"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"화면 분할"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"입력"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"앱 바로가기"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"뒤로"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"돌아가려면 터치패드의 아무 곳이나 세 손가락으로 왼쪽 또는 오른쪽으로 스와이프합니다."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"터치패드에서 세 손가락을 좌우로 움직이는 모습"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"뒤로 동작 애니메이션이 표시된 기기 화면"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"키보드 백라이트"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d단계 중 %1$d단계"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"홈 컨트롤"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 2e62142..9a49201 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ушул скриншотту аныктады."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> жана ачылып турган башка колдонмолор ушул скриншотту аныктады."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Кыска жазууга кошуу"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Экрандан видео жаздырып алуу"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосун жаздырууну токтотосуз"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран бөлүшүлүүдө"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосун бөлүшүүнү токтотосуз"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Тышкы экранга чыгарылууда"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосун тышкы экранга чыгарууну токтотосуз"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -159,7 +160,7 @@
<string name="issuerecord_save_title" msgid="4161043023696751591">"Жаздырылган маселе сакталды"</string>
<string name="issuerecord_save_text" msgid="1205985304551521495">"Көрүү үчүн таптаңыз"</string>
<string name="issuerecord_save_error" msgid="6913040083446722726">"Жаздырылган маселе сакталган жок"</string>
- <string name="issuerecord_start_error" msgid="3402782952722871190">"Маселени жаздыруу башталбай койду"</string>
+ <string name="issuerecord_start_error" msgid="3402782952722871190">"Башталбай койду"</string>
<string name="immersive_cling_title" msgid="8372056499315585941">"Толук экран режимин көрүү"</string>
<!-- no translation found for immersive_cling_description (2717426731830851921) -->
<skip />
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Кулпуну жүзүңүз менен ачтыңыз. Улантуу үчүн басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Жүз таанылды. Улантуу үчүн басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Жүз таанылды. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аныктыгы текшерилди"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аныктыгын текшерүүнү жокко чыгаруу"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Дагы параметрлер"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth Тез бөлүшүү жана Түзмөгүм кайда? сыяктуу функцияларда колдонулат"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth эртең таңда күйөт"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Чогуу угуу"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Чогуу угулууда"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string>
@@ -388,15 +389,15 @@
<string name="qs_record_issue_start" msgid="2979831312582567056">"Баштоо"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Токтотуу"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Мүчүлүштүк тууралуу кабарлоо"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Түзмөгүңүздүн кайсы бөлүгүнө кедергиси тийди?"</string>
- <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Маселенин түрүн тандоо"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Кандай маселеге кабылдыңыз?"</string>
+ <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Маселенин түрүн тандаңыз"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Экрандан видео жаздырып алуу"</string>
<string name="performance" msgid="6552785217174378320">"Иштин майнаптуулугу"</string>
<string name="user_interface" msgid="3712869377953950887">"Колдонуучунун интерфейси"</string>
<string name="thermal" msgid="6758074791325414831">"Жылуулук"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Бир кол режими"</string>
<string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Угуу аппараттары"</string>
- <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Жигердүү"</string>
+ <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Иштеп жатат"</string>
<string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Ажыратылды"</string>
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Угуу аппараттары"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Жаңы түзмөк кошуу"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Көбүрөөк виджеттерди кошуу"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерди ыңгайлаштыруу үчүн кое бербей басып туруңуз"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерди ыңгайлаштыруу"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өчүрүлгөн виджет үчүн колдонмонун сүрөтчөсү"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджет үчүн колдонмонун сүрөтчөсү орнотулууда"</string>
<string name="edit_widget" msgid="9030848101135393954">"Виджетти түзөтүү"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет тандоо"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетти алып салуу"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"тандалган виджетти жайгаштыруу"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ылдый түшүүчү меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана аларга байланыштуу нерселер өчүрүлөт."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Билдирме жок"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңы билдирмелер жок"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивдүү билдирмелер күйүк"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Эгер кыска убакыттын ичинде билдирмелер көп келсе, үн көлөмү жана экрандагы калкыма терезелердин саны эки мүнөткө чейин азайтылат."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өчүрүү"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Билдирмелерди көрүү үчүн кулпуну ачыңыз"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бул түзмөктү ата-энең башкарат"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Бул түзмөк уюмуңузга таандык. Уюмуңуз тармактын трафигин көзөмөлдөй алат"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ойготкуч коюлган жок"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"экран кулпусун киргизүү"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Манжа изинин сенсорун басыңыз. Ал телефондун капталындагы кыска баскыч"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Манжа изинин сенсору"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"аныктыгын текшерүү"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"түзмөккө кирүү"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда иштеп жатат (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Акыркы жолу <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) колдонмосунда иштетилди"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системанын башкаруу элементтери"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системанын колдонмолору"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Бир нече тапшырма аткаруу"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Акыркы колдонмолор"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Экранды бөлүү"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Киргизүү"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Колдонмодогу кыска жолдор"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артка кайтуу"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Кайтуу үчүн сенсордук тактанын каалаган жерин үч манжаңыз менен солго же оңго сүрүңүз."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Үч манжанын оңго жана солго жылып жатканы көрсөтүлгөн сенсордук такта"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Артка жаңсоосунун анимациясы көрсөтүлгөн түзмөктүн экраны"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Баскычтоптун жарыгы"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ичинен %1$d-деңгээл"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Үйдөгү түзмөктөрдү тескөө"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index fb3b377..22dcbe2 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ກວດພົບຮູບໜ້າຈໍນີ້."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ແລະ ແອັບອື່ນໆທີ່ເປີດຢູ່ກວດພົບຮູບໜ້າຈໍນີ້."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ເພີ່ມໃສ່ບັນທຶກ"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ກຳລັງປະມວນຜົນການບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ທ່ານຈະຢຸດການບັນທຶກ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ກຳລັງແບ່ງປັນໜ້າຈໍ"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ທ່ານຈະຢຸດການແບ່ງປັນ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ກຳລັງສົ່ງສັນຍານໜ້າຈໍ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ທ່ານຈະຢຸດການສົ່ງສັນຍານ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ຍົກເລີກການພິສູດຢືນຢັນ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ຕົວເລືອກເພີ່ມເຕີມ"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ຄຸນສົມບັດຕ່າງໆໃຊ້ Bluetooth ເຊັ່ນ: ການແຊຣ໌ດ່ວນ ແລະ ຊອກຫາອຸປະກອນຂອງຂ້ອຍ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ຈະເປີດມື້ອື່ນເຊົ້າ"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ແບ່ງປັນສຽງ"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ກຳລັງແບ່ງປັນສຽງ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ສຽງ"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ຊຸດຫູຟັງ"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ເພີ່ມວິດເຈັດເພີ່ມເຕີມ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ກົດຄ້າງໄວ້ເພື່ອປັບແຕ່ງວິດເຈັດ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ປັບແຕ່ງວິດເຈັດ"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ໄອຄອນແອັບສຳລັບວິດເຈັດທີ່ຖືກປິດການນຳໃຊ້"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ກຳລັງຕິດຕັ້ງໄອຄອນແອັບສຳລັບວິດເຈັດ"</string>
<string name="edit_widget" msgid="9030848101135393954">"ແກ້ໄຂວິດເຈັດ"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ເລືອກວິດເຈັດ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ລຶບວິດເຈັດອອກ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ວາງວິດເຈັດທີ່ເລືອກ"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ສະຫຼັບຜູ້ໃຊ້"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ເມນູແບບດຶງລົງ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯແລະຂໍ້ມູນທັງໝົດໃນເຊດຊັນນີ້ຈະຖືກລຶບອອກ."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ເລີ່ມດຽວນີ້"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ບໍ່ມີການແຈ້ງເຕືອນໃໝ່"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ການແຈ້ງເຕືອນແບບປັບອັດຕະໂນມັດເປີດຢູ່"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ຈາກນີ້ໄປອຸປະກອນຂອງທ່ານຈະຫຼຸດລະດັບສຽງ ແລະ ຈຳນວນປັອບອັບຢູ່ໜ້າຈໍເປັນເວລາສູງສຸດ 2 ນາທີເມື່ອທ່ານໄດ້ຮັບການແຈ້ງເຕືອນຈຳນວນຫຼາຍໃນໄລຍະເວລາສັ້ນໆ."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ປິດ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ປົດລັອກເພື່ອເບິ່ງການແຈ້ງເຕືອນເກົ່າ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ອົງການຂອງທ່ານເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ບໍ່ໄດ້ຕັ້ງໂມງປຸກ"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ໃສ່ຂໍ້ມູນການລັອກໜ້າຈໍ"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ແຕະເຊັນເຊີລາຍນິ້ວມື. ໂດຍເປັນປຸ່ມທີ່ສັ້ນກວ່າເຊິ່ງຢູ່ທາງຂ້າງໂທລະສັບ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ເຊັນເຊີລາຍນິ້ວມື"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ພິສູດຢືນຢັນ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ເຂົ້າອຸປະກອນ"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"ໃຊ້ຢູ່ໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ໃຊ້ຫຼ້າສຸດໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ລະບົບ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ການຄວບຄຸມລະບົບ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ແອັບລະບົບ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ການເຮັດຫຼາຍໜ້າວຽກພ້ອມກັນ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ແອັບຫຼ້າສຸດ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ແບ່ງໜ້າຈໍ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ອິນພຸດ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ທາງລັດແອັບ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ກັບຄືນ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ເພື່ອກັບຄືນ, ໃຫ້ໃຊ້ 3 ນິ້ວປັດຊ້າຍ ຫຼື ຂວາບ່ອນໃດກໍໄດ້ເທິງແຜ່ນສໍາຜັດ."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ແຜ່ນສໍາຜັດສະແດງພາບ 3 ນິ້ວເລື່ອນໄປທາງຂວາ ແລະ ຊ້າຍ"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ໜ້າຈໍອຸປະກອນສະແດງພາບເຄື່ອນໄຫວຂອງທ່າທາງກັບຄືນ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ໄຟປຸ່ມແປ້ນພິມ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ລະດັບທີ %1$d ຈາກ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ການຄວບຄຸມເຮືອນ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index cca7b7f..eef54d1 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ aptiko šią ekrano kopiją."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ ir kitos atidarytos programos aptiko šią ekrano kopiją."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridėti prie užrašo"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Ekrano vaizdo įrašytuvas"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Programos (<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>) turinio įrašymas bus sustabdytas."</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bendrinamas ekranas"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Programos (<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>) turinio bendrinimas bus sustabdytas."</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Perduodamas ekranas"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Programos (<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>) turinio perdavimas bus sustabdytas."</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Atrakinta pagal veidą. Paspauskite, jei norite tęsti."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Veidas atpažintas. Paspauskite, jei norite tęsti."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Veidas atpažintas. Tęskite paspaudę atrakinimo piktogramą."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atšaukti autentifikavimą"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Daugiau parinkčių"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridėkite daugiau valdiklių"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Ilgai paspauskite, kad tinkintumėte valdiklius"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tinkinti valdiklius"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Išjungto valdiklio programos piktograma"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Įdiegiamo valdiklio programos piktograma"</string>
<string name="edit_widget" msgid="9030848101135393954">"Redaguoti valdiklį"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pasirinkite valdiklį"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"pašalinti valdiklį"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"padėti pasirinktą valdiklį"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Perjungti naudotoją"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"išplečiamasis meniu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nėra įspėjimų"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Naujų pranešimų nėra"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptyvieji pranešimai įjungti"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Dabar, gaunant daug pranešimų per trumpą laiką, sumažinamas įrenginio garsumas ir iššokančiųjų langų skaičius ekrane iki dviejų minučių."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Išjungti"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atrakinę matykite senesnius pranešimus"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šį įrenginį tvarko vienas iš tavo tėvų"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šis įrenginys priklauso jūsų organizacijai ir ji gali stebėti tinklo srautą"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenustatyta signalų"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"įvesti ekrano užraktą"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Palieskite piršto antspaudo jutiklį. Tai yra trumpesnis mygtukas telefono šone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Kontrolinio kodo jutiklis"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"nustatytumėte tapatybę"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pasiektumėte įrenginį"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Naudoja <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Neseniai naudojo „<xliff:g id="APP_NAME">%1$s</xliff:g>“ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemos valdikliai"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemos programos"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Kelių užduočių atlikimas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Naujausios programos"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Išskaidyto ekrano režimas"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Įvestis"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Programos šaukiniai"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Grįžti"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Jei norite grįžti, trimis pirštais perbraukite kairėn arba dešinėn bet kurioje jutiklinės dalies vietoje."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Jutiklinė dalis, kurioje rodomi trys dešinėn ir kairėn judantys pirštai"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Įrenginio ekranas, kuriame rodoma grįžimo gesto animacija"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatūros foninis apšvietimas"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d lygis iš %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Namų sistemos valdymas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 7c72c7e..5accf6a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> konstatēja, ka tika veikts ekrānuzņēmums."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> un citas atvērtas lietotnes konstatēja, ka tika veikts ekrānuzņēmums."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pievienot piezīmei"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Ekrāna ierakstītājs"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Tiks pārtraukta lietotnes <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> satura ierakstīšana"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Notiek ekrāna kopīgošana"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Tiks pārtraukta lietotnes <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> satura kopīgošana"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Notiek ekrāna apraide"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Tiks pārtraukta lietotnes <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> satura apraide"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ierīce atbloķēta ar seju. Nospiediet, lai turpinātu."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Seja atpazīta. Nospiediet, lai turpinātu."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Seja atpazīta. Lai turpinātu, nospiediet atbloķēšanas ikonu."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atcelt autentificēšanu"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Citas opcijas"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tādas funkcijas kā “Ātrā kopīgošana” un “Atrast ierīci” izmanto Bluetooth savienojumu"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth savienojums tiks ieslēgts rīt no rīta"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Kopīgot audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Notiek audio kopīgošana…"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumulators: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Austiņas"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pievienot citus logrīkus"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nospiediet un turiet, lai pielāgotu logrīkus."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pielāgot logrīkus"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Lietotnes ikona atspējotam logrīkam"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Tiek instalēta lietotnes ikona logrīkam."</string>
<string name="edit_widget" msgid="9030848101135393954">"Rediģēt logrīku"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"atlasīt logrīku"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"noņemt logrīku"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"novietot atlasīto logrīku"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mainīt lietotāju"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"novelkamā izvēlne"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nav paziņojumu"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nav jaunu paziņojumu"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptīvie paziņojumi ieslēgti"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Jūsu ierīce tagad līdz pat 2 minūtēm samazina skaļuma līmeni un ierobežo uznirstošo elementu skaitu, kad īsā laika posmā saņemat daudzu paziņojumu."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izslēgt"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atbloķējiet vecāku paziņojumu skatīšanai"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šo ierīci pārvalda viens no jūsu vecākiem."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šī ierīce pieder jūsu organizācijai, un jūsu organizācija var uzraudzīt tīkla datplūsmu."</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Pieskarieties, lai iegūtu plašāku informāciju."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nav iestatīts signāls"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ievadīt ekrāna bloķēšanas informāciju"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Pieskarieties pirksta nospieduma sensoram. Tā ir īsākā poga tālruņa malā."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Pirksta nospieduma sensors"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"veiktu autentificēšanu"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"izmantotu ierīci"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"To izmanto lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nesen to izmantoja lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistēma"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistēmas vadīklas"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistēmas lietotnes"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Vairākuzdevumu režīms"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Pēdējās izmantotās lietotnes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekrāna sadalīšana"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ievade"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Lietotņu saīsnes"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atpakaļ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Lai pārietu atpakaļ, ar trim pirkstiem velciet pa kreisi vai pa labi jebkurā vietā uz skārienpaliktņa"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Attēls ar skārienpaliktni, uz kura trīs pirksti kustas pa labi un pa kreisi"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ierīces ekrāns, kurā redzama animācija ar žestu pāriešanai atpakaļ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastatūras fona apgaismojums"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Līmenis numur %1$d, kopā ir %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Mājas kontrolierīces"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index a8baf35..d121b9d 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ја откри оваа слика од екранот."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени апликации ја открија оваа слика од екранот."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај во белешка"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Снимач на екран"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
@@ -129,24 +131,25 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ќе го сопрете снимањето на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <!-- no translation found for share_to_app_chip_accessibility_label (4210256229976947065) -->
+ <skip />
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ќе го сопрете споделувањето на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <!-- no translation found for cast_to_other_device_chip_accessibility_label (1680650146639059938) -->
+ <skip />
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ќе го сопрете емитувањето на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +198,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отклучено со лик. Притиснете за да продолжите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето е препознаено. Притиснете за да продолжите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето е препознаено. Притиснете ја иконата за отклучување за да продолжите."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажување автентикација"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Повеќе опции"</string>
@@ -309,10 +314,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функциите како „Брзо споделување“ и „Најди го мојот уред“ користат Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ќе се вклучи утре наутро"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Споделувај аудио"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Се споделува аудио"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батерија: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string>
@@ -399,7 +402,7 @@
<string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Активно"</string>
<string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Не е поврзано"</string>
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Слушни апарати"</string>
- <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Спари нов уред"</string>
+ <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Спарете нов уред"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за да спарите нов уред"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не можеше да се ажурира зададената вредност"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Зададени вредности"</string>
@@ -477,6 +480,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте повеќе виџети"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Притиснете долго за да ги приспособите виџетите"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Приспособете ги виџетите"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона за апликација за оневозможен виџет"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона за апликација за виџет што се инсталира"</string>
<string name="edit_widget" msgid="9030848101135393954">"Изменување виџети"</string>
@@ -495,6 +500,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"изберете виџет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"отстранете го виџетот"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставете го избраниот виџет"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"паѓачко мени"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијава ќе се избришат."</string>
@@ -548,6 +559,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема известувања"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нови известувања"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивни известув.: вклучено"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Уредот сега ја намалува јачината на звукот и ги намалува скокачките прозорци на екранот до 2 мин. кога добивате многу известувања за кратко време."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Исклучи"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отклучете за да ги видите старите известувања"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Родителот управува со уредов"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацијата е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
@@ -1203,8 +1217,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Допрете за повеќе информации"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Не е поставен аларм"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"внесете PIN/шема/лозинка"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Допрете го сензорот за отпечатоци. Тоа е пократкото копче отстрана на телефонот"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отпечатоци"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"автентицирате"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"внесете уред"</string>
@@ -1346,7 +1359,15 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Се користи од <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Неодамна користено од <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+ <!-- no translation found for shortcut_helper_category_system_controls (3153344561395751020) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_category_system_apps (6001757545472556810) -->
+ <skip />
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Мултитаскинг"</string>
+ <!-- no translation found for shortcutHelper_category_recent_apps (7918731953612377145) -->
+ <skip />
+ <!-- no translation found for shortcutHelper_category_split_screen (1159669813444812244) -->
+ <skip />
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Внесување"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Кратенки за апликации"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
@@ -1363,6 +1384,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"За да се вратите назад, повлечете налево или надесно со три прста каде било на допирната подлога."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Допирната подлога покажува три прста што се движат десно и лево"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екранот на уредот покажува анимација за движење назад"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Осветлување на тастатура"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d од %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за домот"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 9f19680..0bc5028 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്ന ആപ്പും തുറന്നിരിക്കുന്ന മറ്റ് ആപ്പും ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"കുറിപ്പിലേക്ക് ചേർക്കുക"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"സ്ക്രീൻ റെക്കോർഡർ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> റെക്കോർഡ് ചെയ്യുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"സ്ക്രീൻ പങ്കിടുന്നു"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> പങ്കിടുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"സ്ക്രീൻ കാസ്റ്റ് ചെയ്യുന്നു"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> കാസ്റ്റ് ചെയ്യുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്തു. തുടരാൻ അമർത്തുക."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അമർത്തുക."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കുക"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"കൂടുതൽ ഓപ്ഷനുകൾ"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ക്വിക്ക് ഷെയർ, Find My Device പോലുള്ള ഫീച്ചറുകൾ Bluetooth ഉപയോഗിക്കുന്നു"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth നാളെ രാവിലെ ഓണാകും"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ഓഡിയോ പങ്കിടുക"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ഓഡിയോ പങ്കിടുന്നു"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ബാറ്ററി"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ഓഡിയോ"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ഹെഡ്സെറ്റ്"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"കൂടുതൽ വിജറ്റുകൾ ചേർക്കുക"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ ദീർഘനേരം അമർത്തുക"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"പ്രവർത്തനരഹിതമാക്കിയ വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ ഇൻസ്റ്റാൾ ചെയ്തു"</string>
<string name="edit_widget" msgid="9030848101135393954">"വിജറ്റ് എഡിറ്റ് ചെയ്യുക"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"വിജറ്റ് തിരഞ്ഞെടുക്കുക"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"വിജറ്റ് നീക്കം ചെയ്യുക"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"തിരഞ്ഞെടുത്ത വിജറ്റ് നൽകുക"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"പുൾഡൗൺ മെനു"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"പുതിയ അറിയിപ്പുകളൊന്നുമില്ല"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"അഡാപ്റ്റീവ് അറിയിപ്പുകൾ ഓണാണ്"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ചെറിയ കാലയളവിനുള്ളിൽ നിങ്ങൾക്ക് നിരവധി അറിയിപ്പുകൾ ലഭിക്കുമ്പോൾ ഉപകരണം ഇപ്പോൾ വോളിയം കുറയ്ക്കുകയും സ്ക്രീനിൽ പോപ്പ് അപ്പുകൾ രണ്ട് മിനിറ്റ് വരെ ചുരുക്കുകയും ചെയ്യുന്നു."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ഓഫാക്കുക"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"പഴയ അറിയിപ്പുകൾ കാണാൻ അൺലോക്ക് ചെയ്യുക"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"അലാറം സജ്ജീകരിച്ചിട്ടില്ല"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"സ്ക്രീൻ ലോക്ക് നൽകുക"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ഫിംഗർപ്രിന്റ് സെൻസർ സ്പർശിക്കുക. ഇത് ഫോണിന്റെ വശത്തുള്ള ചെറിയ ബട്ടണാണ്"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ഫിംഗർപ്രിന്റ് സെൻസർ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"പരിശോധിച്ചുറപ്പിക്കുക"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ഉപകരണം നൽകുക"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ഉപയോഗിക്കുന്നു"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) അടുത്തിടെ ഉപയോഗിച്ചു"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"സിസ്റ്റം"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"സിസ്റ്റം നിയന്ത്രണങ്ങൾ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"സിസ്റ്റം ആപ്പുകൾ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"മൾട്ടിടാസ്കിംഗ്"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"അടുത്തിടെ ഉപയോഗിച്ച ആപ്പുകൾ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"സ്ക്രീൻ വിഭജന മോഡ്"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ഇൻപുട്ട്"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ആപ്പ് കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"മടങ്ങുക"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"തിരികെ പോകാൻ, ടച്ച്പാഡിൽ എവിടെയെങ്കിലും മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് ഇടത്തേക്കോ വലത്തേക്കോ സ്വൈപ്പ് ചെയ്യുക."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"വലത്തേക്കും ഇടത്തേക്കും ചലിക്കുന്ന മൂന്ന് വിരലുകൾ കാണിക്കുന്ന ടച്ച്പാഡ്"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ബാക്ക് ജെസ്ച്ചറിനായി ആനിമേഷൻ കാണിക്കുന്ന ഉപകരണ സ്ക്രീൻ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"കീബോഡ് ബാക്ക്ലൈറ്റ്"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-ൽ %1$d-ാമത്തെ ലെവൽ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ഹോം കൺട്രോളുകൾ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index a6ab892..be9bcee 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> энэ дэлгэцийн агшныг илрүүлсэн."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> болон бусад нээлттэй апп энэ дэлгэцийн агшныг илрүүлсэн."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Тэмдэглэлд нэмэх"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Дэлгэцийн үйлдэл бичигч"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Та <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-г бичихээ болино"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Дэлгэцийг хуваалцаж байна"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Та <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-г хуваалцахаа болино"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Дэлгэцийг дамжуулж байна"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Та <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-г дамжуулахаа болино"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Царайг таньсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Царайг таньсан. Үргэлжлүүлэх бол түгжээг тайлах дүрсийг дар."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Баталгаажуулагдсан"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Баталгаажуулалтыг цуцлах"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Бусад сонголт"</string>
@@ -382,7 +385,7 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Дэлгэцийн үйлдэл бичих"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Эхлүүлэх"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зогсоох"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Асуудлыг бичих"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Асуудлыг бүртгэх"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Эхлүүлэх"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Зогсоох"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Алдааны мэдээ"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Илүү олон виджет нэмэх"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджетүүдийг өөрчлөхийн тулд удаан дарна уу"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджетүүдийг өөрчлөх"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Идэвхгүй болгосон виджетийн аппын дүрс тэмдэг"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджет суулгах явцын аппын дүрс тэмдэг"</string>
<string name="edit_widget" msgid="9030848101135393954">"Виджетийг засах"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет сонгох"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетийг хасах"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"сонгосон виджетийг байрлуулах"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"эвхмэл цэс"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Мэдэгдэл байхгүй"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Шинэ мэдэгдэл алга"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Дасан зохицох мэдэгдэл ассан"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Таныг богино хугацаанд олон мэдэгдэл авахад таны төхөөрөмж одоо дууны түвшнийг багасгаж, дэлгэц дээрх попапыг хоёр хүртэлх минутын турш багасгана."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Унтраах"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Хуучин мэдэгдлийг харах бол түгжээг тайл"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Энэ төхөөрөмжийг таны эцэг эх удирддаг"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Танай байгууллага энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нэмэлт мэдээлэл авахын тулд товшино уу"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Сэрүүлэг тавиагүй"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"дэлгэцийн түгжээ оруулах"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Хурууны хээ мэдрэгчид хүрнэ үү. Энэ нь утасны хажуу талын арай богино товчлуур юм"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Хурууны хээ мэдрэгч"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"баталгаажуулах"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"төхөөрөмж оруулах"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ашиглаж байна"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Саяхан <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ашигласан"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системийн тохиргоо"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системийн аппууд"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Олон ажил зэрэг хийх"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Саяхны аппууд"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Дэлгэцийг хуваах"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Оролт"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Аппын товчлол"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Буцах"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Буцаж очихын тулд мэдрэгч самбар дээр гурван хуруугаараа хүссэн газраа зүүн эсвэл баруун тийш шударна уу."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Гурван хуруу баруун болон зүүн тийш хөдөлж буйг харуулсан мэдрэгч самбар"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Буцах зангаанд зориулсан анимацийг харуулсан төхөөрөмжийн дэлгэц"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Гарын арын гэрэл"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-с %1$d-р түвшин"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Гэрийн удирдлага"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index cc6e59a..302a685 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ने हा स्क्रीनशॉट डिटेक्ट केला."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> आणि उघडलेल्या इतर अॅप्सनी हा स्क्रीनशॉट डिटेक्ट केला."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"टीप जोडा"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"लिंकचा समावेश करा"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रेकॉर्डर"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"तुम्ही <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> रेकॉर्ड करणे बंद कराल"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेअर करत आहे"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"तुम्ही <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> शेअर करणे बंद कराल"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"स्क्रीन कास्ट करत आहे"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"तुम्ही <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> कास्ट करणे बंद कराल"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"चेहऱ्याने अनलॉक केले आहे. सुरू ठेवण्यासाठी टॅप करा."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ऑथेंटिकेशन रद्द करा"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"अधिक पर्याय"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"आणखी विजेट जोडा"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट कस्टमाइझ करण्यासाठी प्रेस करून ठेवा"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट कस्टमाइझ करा"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद केलेल्या विजेटच्या अॅपचे आयकन"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इंस्टॉल होत असलेल्या विजेटसाठी अॅपचा आयकन"</string>
<string name="edit_widget" msgid="9030848101135393954">"विजेट संपादित करा"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट निवडा"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट काढून टाका"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"निवडलेले विजेट ठेवा"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनू"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अॅप्स आणि डेटा हटवला जाईल."</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"आता सुरू करा"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"सूचना नाहीत"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"नवीन सूचना नाहीत"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"अडॅप्टिव्ह नोटिफिकेशन सुरू आहे"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"कमी वेळेत खूप नोटिफिकेशन मिळल्यास डिव्हाइस आता कमाल २ मिनिटे व्हॉल्यूम, स्क्रीनवरील पॉप-अप कमी करते."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करा"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"जुन्या सूचना पाहण्यासाठी अनलॉक करा"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"तुमच्या संस्थेकडे या डिव्हाइसची मालकी आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"अधिक माहितीसाठी टॅप करा"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म सेट केला नाही"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रीन लॉक एंटर करा"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"फिंगरप्रिंट सेन्सरला स्पर्श करा. हे फोनच्या बाजूला असलेले लहान बटण आहे"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फिंगरप्रिंट सेन्सर"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ऑथेंटिकेट करा"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिव्हाइस एंटर करा"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) द्वारे वापरले जात आहे"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"अलीकडे <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ने वापरले"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टीम"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टीमची नियंत्रणे"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टीम अॅप्स"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"मल्टिटास्किंग"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"अलीकडील अॅप्स"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रीन"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"अॅप शॉर्टकट"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अॅक्सेसिबिलिटी"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"मागे जा"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"मागे जाण्यासाठी, टचपॅडवर कुठेही तीन बोटांनी डावीकडे किंवा उजवीकडे स्वाइप करा."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"तीन बोट उजवीकडे आणि डावीकडे हलताना दाखवणारे टचपॅड"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"मागील जेश्चरसाठी अॅनिमेशन दाखवणारी डिव्हाइस स्क्रीन"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड बॅकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d पैकी %1$d पातळी"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index ced6541..11407f6 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -103,11 +103,12 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> telah mengesan tangkapan skrin ini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan apl lain yang dibuka telah mengesan tangkapan skrin ini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan pada nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Sertakan pautan"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Perakam Skrin"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Mulakan Rakaman?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Apabila anda merakam, Android boleh mengakses apa-apa sahaja yang kelihatan pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati apabila memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Semasa anda merakam, Android boleh mengakses apa-apa sahaja yang kelihatan pada skrin atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati apabila memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Semasa anda merakam apl, Android boleh mengakses apa-apa sahaja yang ditunjukkan atau dimainkan pada apl itu. Oleh hal yang demikian, berhati-hati ketika memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Mulakan rakaman"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Rakam audio"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Anda akan berhenti merakam <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Berkongsi skrin"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Anda akan berhenti berkongsi <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Menghantar skrin"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Anda akan berhenti menghantar <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Dibuka kunci dengan wajah. Tekan untuk meneruskan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dicam. Tekan untuk meneruskan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dicam. Tekan ikon buka kunci untuk meneruskan."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Dibuka kunci dengan wajah. Ketik untuk meneruskan proses."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Pengesahan"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lagi Pilihan"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Ciri seperti Quick Share dan Find My Device menggunakan Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth akan dihidupkan esok pagi"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Kongsi audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Perkongsian audio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Set Kepala"</string>
@@ -384,11 +383,11 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Rakam skrin"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Mula"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Berhenti"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Rekodkan masalah"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Rekodkan Masalah"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Mula"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Hentikan"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Laporan Pepijat"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Pengalaman peranti yang manakah yang terjejas?"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Apakah pengalaman peranti yang terjejas?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Pilih jenis masalah"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Rakam skrin"</string>
<string name="performance" msgid="6552785217174378320">"Prestasi"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan lagi widget"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon apl untuk melumpuhkan widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikon apl untuk widget yang sedang dipasang"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pilih widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alih keluar widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"letakkan widget dipilih"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Tiada pemberitahuan"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Tiada pemberitahuan baharu"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Pemberitahuan boleh suai dihidupkan"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Kelantangan & tetingkap timbul pada skrin peranti anda dikurangkan selama dua minit apabila banyak pemberitahuan diterima dalam masa yang singkat."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Matikan"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat pemberitahuan lama"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Peranti ini diurus oleh ibu bapa anda"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi anda memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketik untuk mendapatkan maklumat lanjut"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Tiada penggera"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"masukkan kunci skrin"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Sentuh penderia cap jari. Penderia cap jari ialah butang yang lebih pendek di sisi telefon"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Penderia cap jari"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"sahkan"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"akses peranti"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Digunakan baru-baru ini oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kawalan sistem"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apl sistem"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Berbilang tugas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apl terbaharu"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Skrin pisah"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Pintasan apl"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Untuk kembali, leret ke kiri atau kanan menggunakan tiga jari di mana-mana sahaja pada pad sentuh."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pad sentuh menunjukkan tiga jari bergerak ke kanan dan kiri"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Skrin peranti menunjukkan animasi untuk gerak isyarat kembali"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Cahaya latar papan kekunci"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tahap %1$d daripada %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kawalan Rumah"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index eae8e1d..8f35ff6 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> က ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> နှင့် အခြားဖွင့်ထားသော အက်ပ်များက ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"မှတ်စုတွင် ထည့်ရန်"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"လင့်ခ်ထည့်သွင်းရန်"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ဖန်သားပြင်ရိုက်ကူးစက်"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ၏ အကြောင်းအရာ ရိုက်ကူးခြင်းကို ရပ်ပါမည်"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ဖန်သားပြင်ကို မျှဝေနေသည်"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ၏ အကြောင်းအရာ မျှဝေခြင်းကို ရပ်ပါမည်"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ဖန်သားပြင်ကို ကာစ်လုပ်နေသည်"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ၏ အကြောင်းအရာ ကာစ်လုပ်ခြင်းကို ရပ်ပါမည်"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဆက်လုပ်ရန် တို့ပါ။"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်ရန်"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"နောက်ထပ်ရွေးစရာများ"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"နောက်ထပ်ဝိဂျက်များ ထည့်ရန်"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ဝိဂျက်များ စိတ်ကြိုက်လုပ်ရန် ကြာကြာနှိပ်ထားပါ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ဝိဂျက်များကို စိတ်ကြိုက်လုပ်ရန်"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ပိတ်ထားသော ဝိဂျက်အတွက် အက်ပ်သင်္ကေတ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ထည့်သွင်းနေသော ဝိဂျက်အတွက် အက်ပ်သင်္ကေတ"</string>
<string name="edit_widget" msgid="9030848101135393954">"ဝိဂျက်ပြင်ရန်"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ဝိဂျက် ရွေးရန်"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ဝိဂျက် ဖယ်ရှားရန်"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ရွေးချယ်ထားသော ဝိဂျက်ကို တင်ရန်"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ဆွဲချမီနူး"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက် မရှိပါ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"အကြောင်းကြားချက်သစ် မရှိပါ"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"အလိုက်သင့်အကြောင်းကြားချက် ဖွင့်ထားသည်"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"သင့်စက်သည် အချိန်တိုအတွင်း အကြောင်းကြားချက်များစွာ ရပါက အသံတိုးပြီး စခရင်ရှိ ပေါ့ပ်အပ်များကို နှစ်မိနစ်အထိ လျှော့ပေးသည်။"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ပိတ်ရန်"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"အကြောင်းကြားချက်ဟောင်းကြည့်ရန် လော့ခ်ဖွင့်ပါ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
@@ -784,7 +796,7 @@
<string name="keyboard_shortcut_join" msgid="3578314570034512676">"သို့မဟုတ်"</string>
<string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"ရှာဖွေစာလုံး ရှင်းထုတ်ရန်"</string>
<string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"လက်ကွက်ဖြတ်လမ်းများ"</string>
- <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ဖြတ်လမ်းလင့်ခ်များ ရှာပါ"</string>
+ <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ဖြတ်လမ်းများ ရှာရန်"</string>
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ဖြတ်လမ်းလင့်ခ် မတွေ့ပါ"</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"စနစ်"</string>
<string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"စာရိုက်ခြင်း"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"နောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"နှိုးစက်ပေးမထားပါ"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ဖန်သားပြင်လော့ခ် ထည့်ရန်"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"လက်ဗွေ အာရုံခံကိရိယာကို တို့ပါ။ ၎င်းသည် ဖုန်းဘေးရှိ ခလုတ်အတို ဖြစ်သည်"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"လက်ဗွေ အာရုံခံကိရိယာ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"အထောက်အထားစိစစ်ရန်"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"စက်ပစ္စည်းသို့ ဝင်ရန်"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) က သုံးနေသည်"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) က လတ်တလောသုံးထားသည်"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"စနစ်"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"စနစ် ထိန်းချုပ်မှုများ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"စနစ် အက်ပ်များ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"တစ်ပြိုင်နက် များစွာလုပ်ခြင်း"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"မကြာသေးမီက အက်ပ်များ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ထည့်သွင်းမှု"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"အက်ပ်ဖြတ်လမ်းလင့်ခ်များ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ပြန်သွားရန်"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ပြန်သွားရန်အတွက် တာ့ချ်ပက်တွင် မည်သည့်နေရာ၌မဆို လက်သုံးချောင်းသုံး၍ ဘယ် (သို့) ညာသို့ ပွတ်ဆွဲပါ။"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"တာ့ချ်ပက်တွင် ဘယ်ညာရွှေ့နေသော လက်သုံးချောင်းကို ပြထားသည်"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"စက်စခရင်တွင် နောက်သို့လက်ဟန်အတွက် လှုပ်ရှားသက်ဝင်ပုံကို ပြထားသည်"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ကီးဘုတ်နောက်မီး"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"အဆင့် %2$d အနက် %1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"အိမ်ထိန်းချုပ်မှုများ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index ebd37f4..cc57e8a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -74,25 +74,25 @@
<string name="global_action_screenshot" msgid="2760267567509131654">"Skjermdump"</string>
<string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hold ulåst er slått av"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har sendt et bilde"</string>
- <string name="screenshot_saving_title" msgid="2298349784913287333">"Lagrer skjermdumpen …"</string>
- <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Lagrer skjermdumpen i jobbprofilen …"</string>
- <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Lagrer skjermdump i den private profilen"</string>
+ <string name="screenshot_saving_title" msgid="2298349784913287333">"Lagrer skjermbildet …"</string>
+ <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Lagrer skjermbildet i jobbprofilen …"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Lagrer skjermbilde i den private profilen"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Skjermdumpen er lagret"</string>
- <string name="screenshot_failed_title" msgid="3259148215671936891">"Kunne ikke lagre skjermdump"</string>
+ <string name="screenshot_failed_title" msgid="3259148215671936891">"Kunne ikke lagre skjermbilde"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ekstern skjerm"</string>
- <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Enheten må være låst opp før skjermdumpen kan lagres"</string>
- <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv å ta skjermdump på nytt"</string>
- <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan ikke lagre skjermdumpen"</string>
- <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper"</string>
- <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Funksjonen for å ta skjermdumper er blokkert av IT-administratoren din"</string>
+ <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Enheten må være låst opp før skjermbildet kan lagres"</string>
+ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv å ta skjermbilde på nytt"</string>
+ <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan ikke lagre skjermbildet"</string>
+ <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermbilder"</string>
+ <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Funksjonen for å ta skjermbilder er blokkert av IT-administratoren din"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
- <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermdumpen"</string>
+ <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermbildet"</string>
<string name="screenshot_share_label" msgid="1653061117238861559">"Del"</string>
- <string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermdumpen"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Utvidet skjermdump"</string>
- <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Avvis skjermdumpen"</string>
+ <string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermbildet"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Utvidet skjermbilde"</string>
+ <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Avvis skjermbildet"</string>
<string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Avvis melding fra jobbprofilen"</string>
- <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermdump"</string>
+ <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermbilde"</string>
<string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Øvre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
<string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
<string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
@@ -100,9 +100,11 @@
<string name="screenshot_work_profile_notification" msgid="203041724052970693">"Lagret i <xliff:g id="APP">%1$s</xliff:g> i jobbprofilen"</string>
<string name="screenshot_private_profile_notification" msgid="1704440899154243171">"Lagret i <xliff:g id="APP">%1$s</xliff:g> i den private profilen"</string>
<string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string>
- <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registrert denne skjermdumpen."</string>
- <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åpne apper har registrert denne skjermdumpen."</string>
+ <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registrert dette skjermbildet."</string>
+ <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åpne apper har registrert dette skjermbildet."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Legg til i notat"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Skjermopptak"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du slutter å ta opp <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deler skjermen"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du slutter å dele <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Caster skjermen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du slutter å caste <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentisering"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere alternativer"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Legg til flere moduler"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Trykk lenge for å tilpasse modulene"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpass moduler"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktivert modul"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikon for en modul som installeres"</string>
<string name="edit_widget" msgid="9030848101135393954">"Endre modul"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velg modul"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern modul"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasser den valgte modulen"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullegardinmeny"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apper og data i denne økten blir slettet."</string>
@@ -533,7 +544,7 @@
<string name="media_projection_task_switcher_action_back" msgid="5324164224147845282">"Bytt tilbake"</string>
<string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Appbytte"</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokkert av IT-administratoren"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skjermdumper er deaktivert av enhetsinnstillingene"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skjermbilder er deaktivert av enhetsinnstillingene"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Fjern alt"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Logg"</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye varsler"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Tilpassbare varsler er på"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Den nye enheten din senker volumet og reduserer antall forgrunnsvinduer på skjermen i opptil to minutter når du mottar mange varsler på kort tid."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slå av"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås opp for å se eldre varsler"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enheten administreres av forelderen din"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasjonen din eier denne enheten og kan overvåke nettverkstrafikken"</string>
@@ -796,7 +810,7 @@
<string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Viser snarveier som åpner apper"</string>
<string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Viser snarveier for den gjeldende appen"</string>
<string name="group_system_access_notification_shade" msgid="1619028907006553677">"Se varsler"</string>
- <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ta skjermdump"</string>
+ <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ta skjermbilde"</string>
<string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Vis snarveier"</string>
<string name="group_system_go_back" msgid="2730322046244918816">"Gå tilbake"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Gå til startskjermen"</string>
@@ -931,7 +945,7 @@
<string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g>-appen"</string>
<string name="notification_channel_alerts" msgid="3385787053375150046">"Varsler"</string>
<string name="notification_channel_battery" msgid="9219995638046695106">"Batteri"</string>
- <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjermdumper"</string>
+ <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjermbilder"</string>
<string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
<string name="notification_channel_setup" msgid="7660580986090760350">"Konfigurering"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"Lagring"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trykk for å få mer informasjon"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm angitt"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"legg inn skjermlåsen"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Trykk på fingeravtrykkssensoren. Det er den korte knappen på siden av telefonen."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeravtrykkssensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentiser"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"åpne enheten"</string>
@@ -1295,8 +1308,8 @@
<string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vil du bytte skjerm?"</string>
<string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Bruk baksidekameraet for å få høyere oppløsning"</string>
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string>
- <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En sammenleggbar enhet blir brettet ut"</string>
- <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En sammenleggbar enhet blir snudd"</string>
+ <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En foldbar enhet blir brettet ut"</string>
+ <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En foldbar enhet blir snudd"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"lagt sammen"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"åpen"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"I bruk av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nylig brukt av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemkontroller"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemapper"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nylige apper"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Delt skjerm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inndata"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-snarveier"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbake"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"For å gå tilbake, sveip til venstre eller høyre med tre fingre hvor som helst på styreflaten."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"En styreflate med tre fingre som beveger seg til høyre og venstre"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Enhetsskjerm med animasjonen for tilbakebevegelse"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrunnslys for tastatur"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemkontroller"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index f83f77c..6b35361 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ले यो स्क्रिनसट भेट्टाएको छ।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> र खुला रहेका अन्य एपहरूले यो स्क्रिनसट भेट्टाएका छन्।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोटमा सेभ गर्नुहोस्"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"लिंक समावेश गर्नुहोस्"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"स्क्रिन रेकर्डर"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> का सामग्री रेकर्ड हुन छाड्ने छन्"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रिन सेयर गरिँदै छ"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> का सामग्री सेयर हुन छाड्ने छन्"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"स्क्रिन कास्ट गरिँदै छ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> का सामग्री कास्ट हुन छाड्ने छन्"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न थिच्नुहोस्।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"अनुहार पहिचान गरियो। जारी राख्न थिच्नुहोस्।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"अनुहार पहिचान गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"अनुहार प्रयोग गरी अनलक गरिएको छ। जारी राख्न ट्याप गर्नुहोस्।"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"प्रमाणीकरण रद्द गर्नुहोस्"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"थप विकल्पहरू"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक सेयर र Find My Device जस्ता सुविधाहरू प्रयोग गर्न ब्लुटुथ चाहिन्छ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लुटुथ भोलि बिहान अन हुने छ"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"अडियो सेयर गर्नुहोस्"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"अडियो सेयर गरिँदै छ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ब्याट्री"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"अडियो"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"थप विजेटहरू हाल्नुहोस्"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेटहरू कस्टमाइज गर्न केही बेरसम्म थिच्नुहोस्"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेटहरू कस्टमाइज गर्नुहोस्"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"अफ गरिएको विजेटको एप जनाउने आइकन"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इन्स्टल भइरहेको विजेटको एप आइकन"</string>
<string name="edit_widget" msgid="9030848101135393954">"विजेट सम्पादन गर्नुहोस्"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चयन गर्नुहोस्"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाउनुहोस्"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चयन गरिएका विजेटका लागि ठाउँ चयन गर्नुहोस्"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनु"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"अहिले न"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कुनै सूचनाहरू छैनन्"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"कुनै पनि नयाँ सूचना छैन"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"एड्याप्टिभ नोटिफिकेसन अन छ"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"तपाईंले छोटो समयमा धेरै नोटिफिकेसन प्राप्त गर्दा तपाईंको डिभाइसले अब दुई मिनेटसम्म भोल्युम र स्क्रिनमा देखिने पप-अपको सङ्ख्या घटाउँछ।"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"अफ गर्नुहोस्"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुराना सूचनाहरू हेर्न अनलक गर्नुहोस्"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"यो डिभाइस तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ र उक्त सङ्गठनले यसको नेटवर्क ट्राफिक अनुगमन गर्न सक्छ"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"थप जानकारी प्राप्त गर्न ट्याप गर्नुहोस्"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म राखिएको छैन"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रिन लक हाल्नुहोस्"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्। यो फोनको साइडमा भएको अलि सानो चाहिँ बटन हो"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फिंगरप्रिन्ट सेन्सर"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"प्रमाणित गर्नुहोस्"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिभाइस हाल्नुहोस्"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ले प्रयोग गरिरहेको छ"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ले हालसालै प्रयोग गरेको"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टम"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टमसँग सम्बन्धित नियन्त्रणहरू"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टम एपहरू"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"एकै पटक एकभन्दा बढी एप चलाउन मिल्ने सुविधा"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"हालसालै चलाइएका एपहरू"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रिन"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"एपका सर्टकटहरू"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"पछाडि जानुहोस्"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"पछाडि जान तिन वटा औँलाले टचप्याडमा कतै छोएर बायाँ वा दायाँतिर स्वाइप गर्नुहोस्।"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"तिन वटा औँला दायाँ र बायाँ सारेको देखाइएको टचप्याड"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"पछाडि जाने जेस्चरको एनिमेसन देखाइएको डिभाइसको स्क्रिन"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"किबोर्ड ब्याकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d मध्ये %1$d औँ स्तर"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कन्ट्रोलहरू"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index d377e01..21f1cfb 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -104,10 +104,6 @@
<color name="people_tile_background">@color/material_dynamic_secondary20</color>
- <!-- Internet Dialog -->
- <color name="connected_network_primary_color">@color/material_dynamic_primary80</color>
- <color name="connected_network_secondary_color">@color/material_dynamic_secondary80</color>
-
<!-- Keyboard shortcut helper dialog -->
<color name="ksh_key_item_color">@*android:color/system_on_surface_variant_dark</color>
</resources>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index 546bf1c..e9dd039f3 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -60,18 +60,6 @@
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
- <style name="TextAppearance.InternetDialog.Active">
- <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textSize">16sp</item>
- <item name="android:textColor">@color/material_dynamic_primary80</item>
- <item name="android:textDirection">locale</item>
- </style>
-
- <style name="TextAppearance.InternetDialog.Secondary.Active">
- <item name="android:textSize">14sp</item>
- <item name="android:textColor">@color/material_dynamic_secondary80</item>
- </style>
-
<style name="ShortcutHelperTheme" parent="@style/ShortcutHelperThemeCommon">
<item name="android:windowLightNavigationBar">false</item>
</style>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 110b59e..1bbb0e3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> heeft dit screenshot waargenomen."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en andere geopende apps hebben dit screenshot waargenomen."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Toevoegen aan notitie"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Schermopname"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Je stopt met het opnemen van <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Scherm delen"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Je stopt met het delen van <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Scherm casten"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Je stopt met het casten van <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontgrendeld via gezicht. Druk om door te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gezicht herkend. Druk om door te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Verificatie annuleren"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opties"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Functies zoals Quick Share en Vind mijn apparaat gebruiken bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth wordt morgenochtend aangezet"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audio delen"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio delen"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterijniveau"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Meer widgets toevoegen"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Houd lang ingedrukt om widgets aan te passen"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets aanpassen"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-icoon voor uitgezette widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App-icoon voor een widget die wordt geïnstalleerd"</string>
<string name="edit_widget" msgid="9030848101135393954">"Widget bewerken"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"widget selecteren"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"widget verwijderen"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"geselecteerde widget plaatsen"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pull-downmenu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen meldingen"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nieuwe meldingen"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Aanpasbare meldingen staan aan"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Je apparaat verlaagt nu het volume en vermindert pop-ups op het scherm gedurende maximaal 2 minuten als je in korte tijd veel meldingen krijgt."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Uitzetten"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontgrendel om oudere meldingen te zien"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dit apparaat wordt beheerd door je ouder"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Je organisatie is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik hier voor meer informatie"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker gezet"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"schermvergrendeling invoeren"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Raak de vingerafdruksensor aan. Dit is de kortere knop aan de zijkant van de telefoon."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Vingerafdruksensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"verifiëren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"apparaat opgeven"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Gebruikt door <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recent gebruikt door <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Systeem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systeemopties"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systeem-apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recente apps"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Gesplitst scherm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Invoer"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-snelkoppelingen"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Terug"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Als je wilt teruggaan, swipe je met 3 vingers naar links of rechts op de touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad met 3 vingers die naar rechts en links bewegen"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Apparaatscherm met animatie voor teruggebaar"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Achtergrondverlichting van toetsenbord"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d van %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Bediening voor in huis"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 2c60c2b..aaf94c9 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏବଂ ଅନ୍ୟ ଓପନ ଆପ୍ସ ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ନୋଟରେ ଯୋଗ କରନ୍ତୁ"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"ସ୍କ୍ରିନ ରେକର୍ଡର"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରିନ୍ ରେକର୍ଡ୍ ସେସନ୍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ଆପଣ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ ରେକର୍ଡ କରିବା ବନ୍ଦ କରିବେ"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ସ୍କ୍ରିନ ସେୟାର କରାଯାଉଛି"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ଆପଣ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ ସେୟାର କରିବା ବନ୍ଦ କରିବେ"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ସ୍କ୍ରିନ କାଷ୍ଟ କରାଯାଉଛି"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ଆପଣ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ କାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ପ୍ରମାଣୀକରଣକୁ ବାତିଲ କରନ୍ତୁ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ଅଧିକ ବିକଳ୍ପ"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ଏବଂ Find My Device ପରି ଫିଚରଗୁଡ଼ିକ ବ୍ଲୁଟୁଥ ବ୍ୟବହାର କରେ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ବ୍ଲୁଟୁଥ ଆସନ୍ତା କାଲି ସକାଳେ ଚାଲୁ ହେବ"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ଅଡିଓ ସେୟାର କରନ୍ତୁ"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ଅଡିଓ ସେୟାର କରାଯାଉଛି"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ବ୍ୟାଟେରୀ"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ଅଡିଓ"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ହେଡସେଟ୍"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ଅଧିକ ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅଧିକ ସମୟ ଦବାନ୍ତୁ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ଅକ୍ଷମ କରାଯାଇଥିବା ୱିଜେଟ ପାଇଁ ଆପ ଆଇକନ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ଏକ ୱିଜେଟ ପାଇଁ ଆପ ଆଇକନକୁ ଇନଷ୍ଟଲ କରାଯାଉଛି"</string>
<string name="edit_widget" msgid="9030848101135393954">"ୱିଜେଟକୁ ଏଡିଟ କରନ୍ତୁ"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ୱିଜେଟ ଚୟନ କରନ୍ତୁ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ୱିଜେଟକୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ଚୟନିତ ୱିଜେଟ ରଖନ୍ତୁ"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍ ବଦଳାନ୍ତୁ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ପୁଲଡାଉନ ମେନୁ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍ ଓ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"କୌଣସି ନୂଆ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ନାହିଁ"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ଆଡେପ୍ଟିଭ ବିଜ୍ଞପ୍ତି ଚାଲୁ ଅଛି"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"କମ ସମୟ ମଧ୍ୟରେ ଅନେକ ବିଜ୍ଞପ୍ତି ପାଇଲେ ଆପଣଙ୍କ ଡିଭାଇସ ଏବେ ଦୁଇ ମିନିଟ ପର୍ଯ୍ୟନ୍ତ ଭଲ୍ୟୁମକୁ କମ କରି ସ୍କ୍ରିନରେ ଥିବା ପପ-ଅପକୁ କମ କରେ।"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ପୁରୁଣା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ଏହି ଡିଭାଇସର ମାଲିକାନା ଆପଣଙ୍କ ସଂସ୍ଥା ପାଖରେ ଅଛି ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକର ନିରୀକ୍ଷଣ କରିପାରେ"</string>
@@ -817,7 +829,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ଡାହାଣପଟର ବା ତଳର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ବାମପଟର ବା ଉପରର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string>
- <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ଇନପୁଟ କରନ୍ତୁ"</string>
+ <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ଇନପୁଟ"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"ପରବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ପୂର୍ବବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="input_access_emoji" msgid="8105642858900406351">"ଇମୋଜି ଆକ୍ସେସ କରନ୍ତୁ"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ଆଲାରାମ ସେଟ ହୋଇନାହିଁ"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ସ୍କ୍ରିନ ଲକ ଲେଖନ୍ତୁ"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ସ୍ପର୍ଶ କରନ୍ତୁ ଏହା ଫୋନର ପାର୍ଶ୍ୱରେ ଥିବା ଛୋଟ ବଟନ ଅଟେ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ଟିପଚିହ୍ନ ସେନ୍ସର୍"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ପ୍ରମାଣୀକରଣ କରନ୍ତୁ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ଡିଭାଇସ୍ ବିଷୟରେ ସୂଚନା ଲେଖନ୍ତୁ"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ଏବେ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ସିଷ୍ଟମ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ସିଷ୍ଟମ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ସିଷ୍ଟମ ଆପ୍ସ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ମଲ୍ଟିଟାସ୍କିଂ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ବର୍ତ୍ତମାନର ଆପ୍ସ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ଇନପୁଟ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ଆପ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ପଛକୁ ଫେରନ୍ତୁ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ପଛକୁ ଫେରିବା ପାଇଁ ଯେ କୌଣସି ସ୍ଥାନରେ ତିନି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ବାମ କିମ୍ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ।"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ଡାହାଣ ଏବଂ ବାମକୁ ତିନି ଆଙ୍ଗୁଠି ମୁଭ କରୁଥିବା ଟଚପେଡ ଦେଖାଉଛି"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ଡିଭାଇସ ସ୍କ୍ରିନ ବେକ ଜେଶ୍ଚର ପାଇଁ ଆନିମେସନ ଦେଖାଉଛି"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"କୀବୋର୍ଡ ବେକଲାଇଟ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ହୋମ କଣ୍ଟ୍ରୋଲ୍ସ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 54a763d..2e6c0da 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ਅਤੇ ਹੋਰ ਖੁੱਲ੍ਹੀਆਂ ਐਪਾਂ ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ਨੋਟ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ਤੁਸੀਂ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ਸਕ੍ਰੀਨ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ਤੁਸੀਂ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਸਾਂਝਾ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ਸਕ੍ਰੀਨ \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ਤੁਸੀਂ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ਪ੍ਰਮਾਣੀਕਰਨ ਰੱਦ ਕਰੋ"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ਹੋਰ ਵਿਕਲਪ"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ਕਵਿੱਕ ਸ਼ੇਅਰ ਅਤੇ Find My Device ਵਰਗੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਬਲੂਟੁੱਥ ਵਰਤਦੀਆਂ ਹਨ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ਬਲੂਟੁੱਥ ਕੱਲ੍ਹ ਸਵੇਰੇ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ਆਡੀਓ ਨੂੰ ਸਾਂਝਾ ਕਰੋ"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ਆਡੀਓ ਨੂੰ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ਆਡੀਓ"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ਹੈੱਡਸੈੱਟ"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ਹੋਰ ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ਵਿਜੇਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ਵਿਜੇਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ਬੰਦ ਵਿਜੇਟ ਲਈ ਐਪ ਪ੍ਰਤੀਕ"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ਸਥਾਪਤ ਕੀਤੇ ਜਾ ਰਹੇ ਵਿਜੇਟ ਲਈ ਐਪ ਪ੍ਰਤੀਕ"</string>
<string name="edit_widget" msgid="9030848101135393954">"ਵਿਜੇਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ਵਿਜੇਟ ਚੁਣੋ"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ਵਿਜੇਟ ਹਟਾਓ"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ਚੁਣੇ ਗਏ ਵਿਜੇਟ ਲਈ ਥਾਂ ਚੁਣੋ"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ਪੁੱਲਡਾਊਨ ਮੀਨੂ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿਚਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ਕੋਈ ਨਵੀਂ ਸੂਚਨਾ ਨਹੀਂ ਹੈ"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ਅਡੈਪਟਿਵ ਸੂਚਨਾਵਾਂ ਚਾਲੂ ਹਨ"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ਘੱਟ ਸਮੇਂ \'ਚ ਕਈ ਸੂਚਨਾਵਾਂ ਮਿਲਣ \'ਤੇ, ਡੀਵਾਈਸ ਹੁਣ ਦੋ ਮਿੰਟਾਂ ਲਈ ਸਕ੍ਰੀਨ \'ਤੇ ਅਵਾਜ਼ ਅਤੇ ਪੌਪ-ਅੱਪ ਘਟਾ ਦਿੰਦਾ ਹੈ।"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ਬੰਦ ਕਰੋ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ਪੁਰਾਣੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ਕੋਈ ਅਲਾਰਮ ਸੈੱਟ ਨਹੀਂ"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ਸਕ੍ਰੀਨ ਲਾਕ ਦਾਖਲ ਕਰੋ"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪਰਸ਼ ਕਰੋ। ਇਹ ਫ਼ੋਨ ਦੇ ਇੱਕ ਪਾਸੇ ਦਿੱਤਾ ਛੋਟਾ ਜਿਹਾ ਬਟਨ ਹੈ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ਪ੍ਰਮਾਣਿਤ ਕਰੋ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ਡੀਵਾਈਸ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ਵੱਲੋਂ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ਹਾਲ ਹੀ ਵਿੱਚ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ਵੱਲੋਂ ਵਰਤਿਆ ਗਿਆ"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ਸਿਸਟਮ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ਸਿਸਟਮ ਸੰਬੰਧੀ ਕੰਟਰੋਲ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ਸਿਸਟਮ ਐਪਾਂ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ਮਲਟੀਟਾਸਕਿੰਗ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ਹਾਲੀਆ ਐਪਾਂ"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ਇਨਪੁੱਟ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ਐਪ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ਵਾਪਸ ਜਾਓ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ਵਾਪਸ ਜਾਣ ਲਈ, ਟੱਚਪੈਡ \'ਤੇ ਕਿਤੇ ਵੀ ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਨੂੰ ਸੱਜੇ ਅਤੇ ਖੱਬੇ ਪਾਸੇ ਵੱਲ ਲਿਜਾਂਦੇ ਹੋਏ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ਡੀਵਾਈਸ ਦੀ ਸਕ੍ਰੀਨ \'ਤੇ ਪਿੱਛੇ ਜਾਣ ਵਾਲੇ ਇਸ਼ਾਰੇ ਲਈ ਐਨੀਮੇਸ਼ਨ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ਹੋਮ ਕੰਟਰੋਲ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 39e243d..464c7c8 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> wykryła ten zrzut ekranu."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> i inne aplikacje wykryły ten zrzut ekranu."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj do notatek"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Dołącz link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Nagrywanie ekranu"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Przestaniesz nagrywać treści z aplikacji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Udostępniam ekran"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Przestaniesz udostępniać treści z aplikacji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Przesyłam ekran"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Przestaniesz przesyłać treści z aplikacji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odblokowano rozpoznawaniem twarzy. Kliknij, aby kontynuować."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Twarz rozpoznana. Kliknij, aby kontynuować."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Twarz rozpoznana. Aby kontynuować, kliknij ikonę odblokowywania."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odblokowano skanem twarzy. Kliknij, aby kontynuować."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anuluj uwierzytelnianie"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Więcej opcji"</string>
@@ -394,7 +395,7 @@
<string name="thermal" msgid="6758074791325414831">"Termografia"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Tryb jednej ręki"</string>
<string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Urządzenia słuchowe"</string>
- <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Aktywny"</string>
+ <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Aktywne"</string>
<string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Rozłączono"</string>
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Urządzenia słuchowe"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sparuj nowe urządzenie"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodaj więcej widżetów"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Przytrzymaj, aby dostosować widżety"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Dostosuj widżety"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacji z wyłączonym widżetem"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacji instalowanego widżetu"</string>
<string name="edit_widget" msgid="9030848101135393954">"Edytuj widżet"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"wybierz widżet"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"usuń widżet"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umieść wybrany widżet"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Brak powiadomień"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Brak nowych powiadomień"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Powiadomienia adaptacyjne włączone"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Urządzenie zmniejszy teraz głośność i ograniczy wyskakujące okienka przez maks. 2 minuty, gdy w krótkim czasie otrzymujesz wiele powiadomień."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Wyłącz"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odblokuj i zobacz starsze powiadomienia"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tym urządzeniem zarządza Twój rodzic"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Twoja organizacja jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Kliknij, aby uzyskać więcej informacji"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nie ustawiono alarmu"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"Wprowadź blokadę ekranu"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotknij czytnika linii papilarnych. To ten krótszy przycisk z boku telefonu"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Czytnik linii papilarnych"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"uwierzytelnij"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"otwórz urządzenie"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Używany przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Ostatnio używany przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemowe elementy sterujące"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacje systemowe"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Wielozadaniowość"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ostatnie aplikacje"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podzielony ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Wprowadzanie"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Skróty do aplikacji"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Wróć"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Aby wrócić, przesuń 3 palcami w lewo lub w prawo w dowolnym miejscu touchpada."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"3 palce na touchpadzie poruszające się w prawo i w lewo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran urządzenia z animacją gestu cofania"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podświetlenie klawiatury"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Poziom %1$d z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Sterowanie domem"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index dc7d564..e1f1050 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -103,11 +103,12 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravador de tela"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Iniciar gravação?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Enquanto você grava, o Android tem acesso a todas as informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Durante a gravação, o Android tem acesso às informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Enquanto você grava um app, o Android tem acesso a todas as informações visíveis ou reproduzidas nele. Tenha cuidado com senhas, detalhes de pagamento, mensagens fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Iniciar gravação"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Gravar áudio"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Você vai parar de gravar o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Você vai parar de compartilhar o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Transmitindo a tela"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Você vai parar de transmitir o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado pelo rosto. Toque para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Recursos como o Quick Share e o Encontre Meu Dispositivo usam Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth será ativado amanhã de manhã"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartilhar áudio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartilhando áudio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone do app para um widget que está sendo instalado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificações adaptáveis ativadas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O dispositivo agora diminui o volume e reduz os pop-ups na tela por até 2 minutos quando você recebe muitas notificações em pouco tempo."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu familiar responsável"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
@@ -1047,7 +1057,7 @@
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Remover"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Controles do disp."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"inserir bloqueio de tela"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toque no sensor de impressão digital. É o menor botão na lateral do smartphone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressão digital"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Tela dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mostrando 3 dedos deslizando para a direita e esquerda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Tela do dispositivo mostrando a animação do gesto de volta"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 0b74941..c8bba38 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"A app <xliff:g id="APPNAME">%1$s</xliff:g> detetou esta captura de ecrã."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A app <xliff:g id="APPNAME">%1$s</xliff:g> e outras apps abertas detetaram esta captura de ecrã."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adicionar a uma nota"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravador de ecrã"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"A processar a gravação de ecrã"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação persistente de uma sessão de gravação de ecrã"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vai parar de gravar <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"A partilhar o ecrã"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vai parar de partilhar <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"A transmitir o ecrã"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vai parar de transmitir <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado com o rosto. Prima para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Prima para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Prima ícone de desbloqueio para continuar"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado com o rosto. Toque para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funcionalidades como a Partilha rápida e o serviço Localizar o meu dispositivo usam o Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth vai ser ativado amanhã de manhã"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partilhar áudio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"A partilhar áudio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ausc. c/ mic. integ."</string>
@@ -388,14 +387,14 @@
<string name="qs_record_issue_start" msgid="2979831312582567056">"Iniciar"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Parar"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Relatório de erro"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Que parte da experiência do disposit. foi afetada?"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Que parte do dispositivo foi afetada?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Selecione o tipo de problema"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Gravação de ecrã"</string>
<string name="performance" msgid="6552785217174378320">"Desempenho"</string>
<string name="user_interface" msgid="3712869377953950887">"Interface do utilizador"</string>
<string name="thermal" msgid="6758074791325414831">"Térmico"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo para uma mão"</string>
- <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Dispositivos auditivos"</string>
+ <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Disp. auditivos"</string>
<string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Ativos"</string>
<string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Desligados"</string>
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Dispositivos auditivos"</string>
@@ -475,8 +474,10 @@
<string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Ignorar"</string>
<string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Adicionar, remover e reordenar widgets neste espaço"</string>
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicionar mais widgets"</string>
- <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha premido para personalizar os widgets"</string>
+ <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar os widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone da app do widget desativado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone da app para um widget que está a ser instalado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Não existem novas notificações"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificações adaptáveis ativas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O disp. diminui o vol. e reduz os pop-ups por até 2 min quando recebe muitas notificações seguidas."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie e veja notificações antigas"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerido pelos teus pais"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede."</string>
@@ -627,7 +637,7 @@
<string name="stream_voice_call" msgid="7468348170702375660">"Chamada"</string>
<string name="stream_system" msgid="7663148785370565134">"Sistema"</string>
<string name="stream_ring" msgid="7550670036738697526">"Toque"</string>
- <string name="stream_music" msgid="2188224742361847580">"Suporte de dados"</string>
+ <string name="stream_music" msgid="2188224742361847580">"Multimédia"</string>
<string name="stream_alarm" msgid="16058075093011694">"Alarme"</string>
<string name="stream_notification" msgid="7930294049046243939">"Notificação"</string>
<string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"introduzir bloqueio de ecrã"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toque no sensor de impressões digitais. É o botão mais pequeno na parte lateral do telemóvel"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressões digitais"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"entrar no dispositivo"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em utilização pela app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pela app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controlos do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Execução de várias tarefas em simultâneo"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ecrã dividido"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para retroceder, deslize rapidamente para a esquerda ou direita com três dedos em qualquer parte do touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad a mostrar três dedos a moverem-se para a direita e esquerda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ecrã de dispositivo a mostrar uma animação do gesto para retroceder"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controlos domésticos"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index dc7d564..e1f1050 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -103,11 +103,12 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Gravador de tela"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Iniciar gravação?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Enquanto você grava, o Android tem acesso a todas as informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Durante a gravação, o Android tem acesso às informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Enquanto você grava um app, o Android tem acesso a todas as informações visíveis ou reproduzidas nele. Tenha cuidado com senhas, detalhes de pagamento, mensagens fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Iniciar gravação"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Gravar áudio"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Você vai parar de gravar o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Você vai parar de compartilhar o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Transmitindo a tela"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Você vai parar de transmitir o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado pelo rosto. Toque para continuar."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Recursos como o Quick Share e o Encontre Meu Dispositivo usam Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth será ativado amanhã de manhã"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartilhar áudio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartilhando áudio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone do app para um widget que está sendo instalado"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificações adaptáveis ativadas"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O dispositivo agora diminui o volume e reduz os pop-ups na tela por até 2 minutos quando você recebe muitas notificações em pouco tempo."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu familiar responsável"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
@@ -1047,7 +1057,7 @@
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Remover"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Controles do disp."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"inserir bloqueio de tela"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toque no sensor de impressão digital. É o menor botão na lateral do smartphone"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressão digital"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles do sistema"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefas"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Tela dividida"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mostrando 3 dedos deslizando para a direita e esquerda"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Tela do dispositivo mostrando a animação do gesto de volta"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index f735be4..ff4836e 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a detectat această captură de ecran."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> și alte aplicații deschise au detectat această captură de ecran."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adaugă în notă"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Recorder pentru ecran"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Nu vei mai înregistra <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Se permite accesul la ecran"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Nu vei mai permite accesul la <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Se proiectează ecranul"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Nu vei mai proiecta <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S-a deblocat cu ajutorul feței. Apasă pentru a continua."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Chipul a fost recunoscut. Apasă pentru a continua."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Chip recunoscut. Apasă pictograma Deblocare ca să continui."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulează autentificarea"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mai multe opțiuni"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funcții precum Quick Share și Găsește-mi dispozitivul folosesc Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se va activa mâine dimineață"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Trimite audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Se permite accesul la conținutul audio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Căști"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adaugă mai multe widgeturi"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Apasă lung pentru a personaliza widgeturi"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizează widgeturile"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Pictograma aplicației pentru widgetul dezactivat"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Pictograma aplicației pentru un widget care se instalează"</string>
<string name="edit_widget" msgid="9030848101135393954">"Editează widgetul"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selectează un widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"elimină widgetul"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasează widgetul selectat"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Schimbă utilizatorul"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"meniu vertical"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Începe acum"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nicio notificare"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nicio notificare nouă"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificări adaptabile activate"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Dispozitivul reduce acum volumul și numărul de ferestre pop-up de pe ecran timp de până la două minute când primești multe notificări într-un timp scurt"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Dezactivează"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Deblochează ca să vezi notificări vechi"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dispozitivul este gestionat de unul dintre părinți"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizația ta deține acest dispozitiv și poate monitoriza traficul de rețea"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Atinge pentru mai multe informații"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nicio alarmă setată"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"intră în blocarea ecranului"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Atinge senzorul de amprentă. Acesta este butonul mai scurt de pe partea laterală a telefonului"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor de amprentă"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifică-te"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"Accesează dispozitivul"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Se folosește pentru <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Folosit recent de <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Comenzile sistemului"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicații de sistem"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicații recente"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ecran împărțit"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Intrare"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Comenzi rapide pentru aplicații"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Înapoi"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pentru a reveni, glisează spre stânga sau spre dreapta cu trei degete oriunde pe touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad cu trei degete care se mișcă spre dreapta și spre stânga"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ecran de dispozitiv cu o animație pentru gestul Înapoi"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Iluminarea din spate a tastaturii"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivelul %1$d din %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Comenzi pentru locuință"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index d7973fd..3860d6f 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" обнаружило создание скриншота."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" и другие запущенные продукты обнаружили создание скриншота."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавить в заметку"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Запись видео с экрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Запись в приложении <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> будет прекращена."</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Демонстрация экрана"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Демонстрация экрана приложения <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> будет прекращена."</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Трансляция экрана"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Трансляция из приложения <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> будет прекращена."</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблокировано сканированием лица. Нажмите, чтобы продолжить."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицо распознано. Нажмите, чтобы продолжить."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицо распознано. Нажмите на значок разблокировки."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификация выполнена"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Отмена распознавания лица"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ещё"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth используется в таких функциях и сервисах, как \"Быстрая отправка\" и \"Найти устройство\""</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth включится завтра утром"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Отправить аудио"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Отправка аудио"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудиоустройство"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string>
@@ -403,7 +404,7 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Нажмите, чтобы подключить новое устройство"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не удалось обновить набор настроек."</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор настроек"</string>
- <string name="live_caption_title" msgid="8916875614623730005">"Автоматические субтитры"</string>
+ <string name="live_caption_title" msgid="8916875614623730005">"Автосубтитры"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблокировать микрофон устройства?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблокировать камеру устройства?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблокировать камеру и микрофон устройства?"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавить виджеты"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Нажмите и удерживайте, чтобы настроить виджеты."</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Настроить виджеты"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок приложения для отключенного виджета"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок приложения для устанавливаемого виджета"</string>
<string name="edit_widget" msgid="9030848101135393954">"Изменить виджет"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбрать виджет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"удалить виджет"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"разместить выбранный виджет"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"раскрывающееся меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нет уведомлений."</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Новых уведомлений нет"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивные уведомления включены"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Если за короткий промежуток времени придет много уведомлений, громкость звуков и количество всплывающих окон будут уменьшены на срок до двух минут."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Отключить"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблокируйте, чтобы увидеть уведомления"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Устройством управляет один из родителей."</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Нет будильников"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"разблокировать экран"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Коснитесь сканера отпечатков пальцев. Это самая короткая кнопка сбоку на телефоне."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер отпечатков пальцев"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"выполнить аутентификацию"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"указать устройство"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Сейчас используется приложением \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Недавно использовалось приложением \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Управление системой"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системные приложения"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Многозадачность"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Недавние приложения"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделение экрана"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ввод"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ярлыки приложений"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Чтобы вернуться, проведите тремя пальцами влево или вправо по сенсорной панели."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Три пальца двигаются вправо и влево по сенсорной панели"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"На экране устройства показана анимация для жеста \"Назад\""</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка клавиатуры"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Уровень %1$d из %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Управление домом"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index dac0c42..30a3b56 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> සහ අනෙකුත් විවෘත යෙදුම් මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"සටහනට එක් කරන්න"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"තිර රෙකෝඩරය"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ඔබ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> පටිගත කිරීම නතර කරනු ඇත"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"තිරය බෙදා ගැනීම"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ඔබ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> බෙදා ගැනීම නතර කරනු ඇත"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"විකාශ තිරය"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ඔබ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> විකාශය නතර කරනු ඇත"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"මුහුණ මගින් අගුලු හරින ලදි. ඉදිරියට යාමට ඔබන්න."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට ඔබන්න."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"සත්යාපනය විය"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"සත්යාපනය අවලංගු කරන්න"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"තවත් විකල්ප"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ඉක්මන් බෙදා ගැනීම සහ මගේ උපාංගය සෙවීම වැනි විශේෂාංග බ්ලූටූත් භාවිත කරයි"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"බ්ලූටූත් හෙට උදේ සක්රීය වෙයි"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ශ්රව්ය බෙදා ගන්න"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ශ්රව්ය බෙදා ගැනීම"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ශ්රව්ය"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"හෙඩ්සෙටය"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"තවත් විජට් එක් කරන්න"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"විජට් අභිරුචිකරණය කිරීමට දිගු ඔබන්න"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"විජට්ටු අභිරුචි කරන්න"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"අබල කළ විජට් සඳහා යෙදුම් නිරූපකය"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"විජට්ටුවක් සඳහා ස්ථාපන කරනු ලබන යෙදුම් නිරූපකය"</string>
<string name="edit_widget" msgid="9030848101135393954">"විජට්ටු සංස්කරණ කරන්න"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"විජට්ටුව තෝරන්න"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"විජට්ටුව ඉවත් කරන්න"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"තෝරන ලද විජට්ටුව තබන්න"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"නිපතන මෙනුව"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"දැනුම්දීම් නැත"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"නව දැනුම්දීම් නැත"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"අනුවර්තන දැනුම්දීම් ක්රියාත්මකයි"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ඔබේ උපාංගය දැන් ශබ්දය අඩු කරන අතර ඔබට කෙටි කාල පරාසයක් තුළ බොහෝ දැනුම්දීම් ලැබෙන විට තිරය මත උත්පතන විනාඩි දෙකක් දක්වා අඩු කරයි."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ක්රියාවිරහිත කරන්න"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"පැරණි දැනුම්දීම් බැලීමට අගුළු හරින්න"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"මෙම උපාංගය ඔබගේ මාපියන්ගෙන් අයකු විසින් කළමනාකරණය කෙරේ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ඔබේ සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"එලාම සකසා නැත"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"තිර අගුල ඇතුළු කරන්න"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න. එය දුරකථනයේ පැත්තේ ඇති කෙටි බොත්තමයි"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ඇඟිලි සලකුණු සංවේදකය"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"සත්යාපනය කරන්න"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"උපාංගය ඇතුළු කරන්න"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> භාවිත කරයි (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> විසින් මෑතකදී භාවිත කරන ලදි (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"පද්ධතිය"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"පද්ධති පාලන"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"පද්ධති යෙදුම්"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"බහුකාර්ය"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"මෑත යෙදුම්"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"බෙදුම් තිරය"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ආදානය"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"යෙදුම් කෙටිමං"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්රවේශ්යතාව"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ආපස්සට යන්න"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ආපසු යාමට, ස්පර්ශ පුවරුවේ ඕනෑම තැනක ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ඇඟිලි තුනක් දකුණට සහ වමට චලනය වන බව පෙන්වන ස්පර්ශක පුවරුව"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"පසුපස අභිනය සඳහා සජීවිකරණය පෙන්වන උපාංග තිරය"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"යතුරු පුවරු පසු ආලෝකය"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dන් %1$d වැනි මට්ටම"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"නිවෙස් පාලන"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 0014117..cf35af0 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikácia <xliff:g id="APPNAME">%1$s</xliff:g> zaznamenala túto snímku obrazovky."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ďalšie otvorené aplikácie zaznamenali túto snímku obrazovky."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridať do poznámky"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Rekordér obrazovky"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Prestante zaznamenávať obsah aplikácie <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Zdieľa sa obrazovka"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Prestanete zdieľať obsah aplikácie <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Prenáša sa obrazovka"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Prestanete prenášať obsah aplikácie <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odomknuté tvárou. Pokračujte stlačením."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Tvár bola rozpoznaná. Pokračujte stlačením."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Tvár bola rozpoznaná. Pokračujte stlačením ikony odomknutia"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušiť overenie"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ďalšie možnosti"</string>
@@ -382,8 +385,8 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Rekordér obrazovky"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Začať"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ukončiť"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Problém s nahrávaním"</string>
- <string name="qs_record_issue_start" msgid="2979831312582567056">"Začnite"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Nahrať problém"</string>
+ <string name="qs_record_issue_start" msgid="2979831312582567056">"Začať"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Zastavte"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Hlásenie chyby"</string>
<string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Čo v zariadení bolo ovplyvnené?"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridať ďalšie miniaplikácie"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Miniaplikácie prispôsobíte dlhým stlačením"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prispôsobiť miniaplikácie"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona deaktivovanej miniaplikácie"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona inštalovanej miniaplikácie"</string>
<string name="edit_widget" msgid="9030848101135393954">"Upraviť miniaplikáciu"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrať miniaplikáciu"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstrániť miniaplikáciu"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"prepnúť vybranú miniaplikáciu"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbaľovacia ponuka"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žiadne upozornenia"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Žiadne nové upozornenia"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptívne upozornenia sú zap."</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Zariadenie teraz zníži hlasitosť a zredukuje vyskakovacie okná na obrazovke na dve až štyri minúty, keď dostanete veľa upozornení v krátkom čase."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnúť"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odomknutím zobrazíte staršie upozornenia"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zariadenie spravuje tvoj rodič"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím si zobrazíte ďalšie informácie"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Žiadny budík"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"zadať zámku obrazovky"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotknite sa senzora odtlačkov prstov. Ide o kratšie tlačidlo na boku telefónu."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor odtlačkov prstov"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"overte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"vstúpte do zariadenia"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Využíva <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedávno využila aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Systém"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Ovládanie systému"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systémové aplikácie"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedávne aplikácie"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Rozdelená obrazovka"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vstup"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Odkazy do aplikácií"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Prejsť späť"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ak chcete prejsť späť, potiahnite doľava alebo doprava troma prstami kdekoľvek na touchpade."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tri prsty na touchpade pohybujúce sa doprava a doľava"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Obrazovka zariadenia, na ktorej je animácia gesta späť"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvietenie klávesnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládanie domácnosti"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 4428c0c..c493c5e 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je zaznala ta posnetek zaslona."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> in druge odprte aplikacije so zaznale ta posnetek zaslona."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj v zapisek"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Snemalnik zaslona"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obdelava videoposnetka zaslona"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Nenehno obveščanje o seji snemanja zaslona"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ustavili boste snemanje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deljenje zaslona"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ustavili boste deljenje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Predvajanje vsebine zaslona"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ustavili boste predvajanje aplikacije <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odklenjeno z obrazom. Pritisnite za nadaljevanje."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obraz je prepoznan. Pritisnite za nadaljevanje."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obraz je prepoznan. Za nadaljevanje pritisnite ikono za odklepanje."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Prekliči preverjanje pristnosti"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Več možnosti"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije, kot sta Hitro deljenje in Poišči mojo napravo, uporabljajo Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se bo vklopil jutri zjutraj"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deli zvok"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Poteka deljenje zvoka"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvok"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalke z mikrofonom"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte več pripomočkov"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pridržite za prilagajanje pripomočkov"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagajanje pripomočkov"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogočen pripomoček"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za nameščanje pripomočka"</string>
<string name="edit_widget" msgid="9030848101135393954">"Urejanje pripomočka"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izberite pripomoček"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranitev pripomočka"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavitev izbranega pripomočka"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"spustni meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ni obvestil"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ni novih obvestil"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljiva obvestila so vklopljena"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Naprava za do dve minuti zmanjša glasnost in število pojavnih elementov na zaslonu, ko v kratkem času prejmete veliko obvestil."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izklopi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odklenite za ogled starejših obvestil"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"To napravo upravlja tvoj starš"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je lastnica te naprave in lahko nadzira omrežni promet"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dotaknite se za več informacij"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ni nastavljenih alarmov"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"odklenite zaslon"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotaknite se tipala prstnih odtisov. To je krajši gumb ob strani telefona."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Tipalo prstnih odtisov"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"preverjanje pristnosti"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"vstop v napravo"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Uporablja aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno uporabljala aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemski kontrolniki"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Večopravilnost"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Razdeljen zaslon"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vnos"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Bližnjice do aplikacij"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazaj"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Za pomik nazaj povlecite levo ali desno s tremi prsti kjer koli na sledilni ploščici."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sledilna ploščica s tremi prsti, ki se premikajo desno in levo"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Zaslon naprave z animacijo, ki prikazuje potezo za pomik nazaj"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Osvetlitev tipkovnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Stopnja %1$d od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrolniki za dom"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 537134d..e189e9c 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> zbuloi këtë pamje ekrani."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dhe aplikacionet e tjera të hapura zbuluan këtë pamje ekrani."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Shto te shënimi"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Regjistruesi i ekranit"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
@@ -129,24 +131,25 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Do të ndalosh regjistrimin me <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <!-- no translation found for share_to_app_chip_accessibility_label (4210256229976947065) -->
+ <skip />
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Do të ndalosh ndarjen e <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <!-- no translation found for cast_to_other_device_chip_accessibility_label (1680650146639059938) -->
+ <skip />
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Do të ndalosh transmetimin e <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +198,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"U shkyç me fytyrë. Shtyp për të vazhduar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Fytyra u njoh. Shtyp për të vazhduar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Fytyra u njoh. Shtyp ikonën e shkyçjes për të vazhduar."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulo vërtetimin"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsione të tjera"</string>
@@ -475,6 +480,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Shto miniaplikacione të tjera"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Shtyp gjatë për të personalizuar miniaplikacionet"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizo miniaplikacionet"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona e aplikacionit për miniaplikacionin e çaktivizuar"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona e aplikacionit për një miniaplikacion që po instalohet"</string>
<string name="edit_widget" msgid="9030848101135393954">"Modifiko miniaplikacionin"</string>
@@ -493,6 +500,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"zgjidh miniaplikacionin"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"hiq miniaplikacionin"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"vendos miniaplikacionin e zgjedhur"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyja me tërheqje poshtë"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
@@ -546,6 +559,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nuk ka njoftime të reja"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Njoftimet me përshtatje janë aktive"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Pajisja jote tani ul volumin dhe zvogëlon numrin e dritareve kërcyese në ekran për deri në dy minuta kur ti merr shumë njoftime në një periudhë të shkurtër kohe."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Çaktivizo"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Shkyç për të parë njoftimet e vjetra"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kjo pajisje menaxhohet nga prindi yt"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizata jote e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
@@ -1201,8 +1217,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trokit për më shumë informacione"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nuk është caktuar asnjë alarm"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"hyr te kyçja e ekranit"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Prek sensorin e gjurmës së gishtit. Është butoni më i shkurtër në pjesën anësore të telefonit"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensori i gjurmës së gishtit"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"për ta vërtetuar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"për të hyrë në pajisje"</string>
@@ -1344,7 +1359,15 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Në përdorim nga <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Përdorur së fundi nga <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistemi"</string>
+ <!-- no translation found for shortcut_helper_category_system_controls (3153344561395751020) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_category_system_apps (6001757545472556810) -->
+ <skip />
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Kryerja e shumë detyrave"</string>
+ <!-- no translation found for shortcutHelper_category_recent_apps (7918731953612377145) -->
+ <skip />
+ <!-- no translation found for shortcutHelper_category_split_screen (1159669813444812244) -->
+ <skip />
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Hyrja"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Shkurtoret e aplikacionit"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
@@ -1361,6 +1384,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kthehu prapa"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Për t\'u kthyer prapa, rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta kudo në bllokun me prekje."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Blloku me prekje që tregon tre gishta që lëvizin djathtas dhe majtas"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekrani i pajisjes që tregon një animacion për gjestin e kthimit prapa"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Drita e sfondit e tastierës"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveli: %1$d nga %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrollet e shtëpisë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 1969746..aac4c0b 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Апликација <xliff:g id="APPNAME">%1$s</xliff:g> је открила овај снимак екрана."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и друге отворене апликације су откриле овај снимак екрана."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај у белешку"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Снимач екрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Зауставићете снимање за: <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екран се дели"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Зауставићете дељење за: <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Пребацује се екран"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Зауставићете пребацивање за: <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Откључано је лицем. Притисните да бисте наставили."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лице је препознато. Притисните да бисте наставили."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажите потврду идентитета"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Још опција"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте још виџета"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Дуги притисак за прилагођавање виџета"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Прилагоди виџете"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона апликације за онемогућен виџет"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона апликације за виџет који се инсталира"</string>
<string name="edit_widget" msgid="9030848101135393954">"Измени виџет"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"изаберите виџет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"уклоните виџет"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставите изабрани виџет"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема обавештења"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нових обавештења"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Прилаг. обавештења су укључена"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Уређај сада смањује звук и број искачућих прозора на екрану до 2 минута кад примите много обавештења у кратком року."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Искључи"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Откључајте за старија обавештења"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Овим уређајем управља родитељ"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Није подешен"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"унесите откључавање екрана"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Додирните сензор за отисак прста. То је краће дугме на бочној страни телефона"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отисак прста"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"потврдите идентитет"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Користе <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Недавно користила апликација <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системске контроле"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системске апликације"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Обављање више задатака истовремено"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Недавне апликације"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Подељени екран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Унос"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Пречице за апликације"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Да бисте се вратили, превуците улево или удесно са три прста било где на тачпеду."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Тачпед са приказом три прста који се померају удесно и улево"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екран уређаја са приказом анимације покрета за назад"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Позадинско осветљење тастатуре"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. ниво од %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроле за дом"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 6f2c07b..39d81b9 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> identifierade skärmbilden."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> och andra öppna appar identifierade skärmbilden."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lägg till i anteckning"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Skärminspelare"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du slutar att spela in <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skärmen delas"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du slutar att dela <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Skärmen castas"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du slutar att casta <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet har identifierats. Tryck för att fortsätta."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentiseringen"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fler alternativ"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktioner som Snabbdelning och Hitta min enhet använder Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth aktiveras i morgon bitti"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Dela ljud"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Delar ljud"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ljud"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lägg till fler widgetar"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tryck länge för att anpassa widgetar"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Anpassa widgetar"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon för inaktiverad widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikon för en widget som installeras"</string>
<string name="edit_widget" msgid="9030848101135393954">"Redigera widget"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"välj widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ta bort widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placera vald widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Byt användare"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullgardinsmeny"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Inga aviseringar"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Det finns inga nya aviseringar"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Anpassade aviseringar är på"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Om du får många aviseringar tätt inpå varandra sänker nu enheten volymen och minskar antalet popuper i upp till två minuter."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Inaktivera"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås upp för att se äldre aviseringar"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Den här enheten hanteras av din förälder"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisationen äger den här enheten och kan övervaka nätverkstrafiken"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryck för mer information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Inget inställt alarm"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ange skärmlåset"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Tryck på fingeravtryckssensorn. Det är den mindre knappen på sidan av telefonen"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeravtryckssensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentisera"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ange enhet"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Används av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Användes nyligen av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systeminställningar"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemappar"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multikörning"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Senaste apparna"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Delad skärm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ingång"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Genvägar till appar"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tillbaka"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Gå tillbaka genom att svepa åt vänster eller höger med tre fingrar var som helst på styrplattan."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tre fingrar rör sig åt höger och vänster på en styrplatta"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"En enhetsskärm visar en animation för rörelsen Tillbaka"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrundsbelysning för tangentbord"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hemstyrning"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index a15d975..253acf0 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -103,11 +103,13 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> imetambua picha hii ya skrini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> na zingine zinazotumika zimetambua picha hii ya skrini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ongeza kwenye dokezo"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Kinasa Skrini"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Ungependa kuanza kurekodi?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Unaporekodi, Android inaweza kufikia kitu chochote kitakachoonekana kwenye skrini yako au kuchezwa kwenye kifaa chako. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Unaporekodi, Android inaweza kufikia kitu chochote kitakachoonekana kwenye skrini yako au kuchezwa kwenye kifaa chako. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Unaporekodi programu, Android inaweza kufikia kitu chochote kitakachoonekana au kuchezwa kwenye programu hiyo. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Anza kurekodi"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Rekodi sauti"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Utaacha kurekodi maudhui ya <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Inaruhusu ufikiaji kwenye skrini"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Utakomesha ufikiaji wa maudhui ya <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Inatuma skrini"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Utaacha kutuma maudhui ya <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili uendelee."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Uso umetambuliwa. Bonyeza ili uendelee."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili uendelee."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ghairi Uthibitishaji"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Chaguo Zaidi"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Vipengele kama vile Kutuma Haraka na Tafuta Kifaa Changu hutumia Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth itawaka kesho asubuhi"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sikiliza pamoja na wengine"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Mnasikiliza pamoja"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Sauti"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Vifaa vya sauti"</string>
@@ -384,7 +385,7 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Rekodi ya skrini"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Anza kurekodi"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Acha kurekodi"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"Hitilafu ya Kurekodi"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"Rekodi Hitilafu"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"Anza"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"Simamisha"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Ripoti ya Hitilafu"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weka wijeti zingine"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Bonyeza kwa muda mrefu uweke mapendeleo ya wijeti"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Badilisha wijeti upendavyo"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Aikoni ya programu ya wijeti iliyozimwa"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Aikoni ya programu ya wijeti inayowekwa"</string>
<string name="edit_widget" msgid="9030848101135393954">"Badilisha wijeti"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chagua wijeti"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ondoa wijeti"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"weka wijeti uliyochagua"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyu ya kuvuta chini"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Hakuna arifa"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Hakuna arifa mpya"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Umewasha arifa zinazojirekebisha"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Sasa kifaa chako kinapunguza sauti na idadi ya madirisha ibukizi kwenye skrini kwa hadi dakika mbili ukipokea arifa nyingi kwa muda mfupi."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Zima"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Fungua ili uone arifa za zamani"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kifaa hiki kinadhibitiwa na mzazi wako"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Shirika lako linamiliki kifaa hiki na huenda likafuatilia trafiki ya mtandao"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Gusa ili upate maelezo zaidi"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Hujaweka kengele"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"weka kifunga skrini"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Gusa kitambuzi cha alama ya kidole. Ni kitufe kifupi zaidi kilicho pembeni mwa simu"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Kitambua alama ya kidole"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"thibitisha"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"weka kifaa"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Inatumiwa na <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Ilitumiwa hivi majuzi na <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Mfumo"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Vidhibiti vya mfumo"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Programu za mfumo"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Majukumu mengi"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Programu za hivi majuzi"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Gawa skrini"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Kifaa cha kuingiza data"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Njia za mikato za programu"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Rudi nyuma"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ili kurudi nyuma, telezesha vidole vitatu kushoto au kulia mahali popote kwenye padi ya kugusa."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Padi ya kugusa inayoonyesha vidole vitatu vikisonga kulia na kushoto"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Skrini ya kifaa inayoonyesha uhuishaji wa mguso wa nyuma"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Mwanga chini ya kibodi"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Kiwango cha %1$d kati ya %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Dhibiti Vifaa Nyumbani"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index c9e17ff..159c4c57 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> கண்டறிந்துள்ளது."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> மற்றும் திறந்திருக்கும் பிற ஆப்ஸ் கண்டறிந்துள்ளன."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"குறிப்பில் சேர்"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"ஸ்கிரீன் ரெக்கார்டர்"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ஆப்ஸை ரெக்கார்டு செய்வதை நிறுத்துவீர்கள்"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"திரையைப் பகிர்கிறது"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ஆப்ஸைப் பகிர்வதை நிறுத்துவீர்கள்"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"திரையை அலைபரப்புகிறது"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ஆப்ஸை அலைபரப்புவதை நிறுத்துவீர்கள்"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர அழுத்தவும்."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அழுத்தவும்."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அன்லாக் ஐகானை அழுத்தவும்."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"அங்கீகரிப்பை ரத்துசெய்"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"கூடுதல் விருப்பங்கள்"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"விரைவுப் பகிர்தல், Find My Device போன்ற அம்சங்கள் புளூடூத்தைப் பயன்படுத்துகின்றன"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"நாளை காலை புளூடூத் இயக்கப்படும்"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ஆடியோவைப் பகிர்"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ஆடியோ பகிரப்படுகிறது"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> பேட்டரி"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ஆடியோ"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ஹெட்செட்"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"கூடுதல் விட்ஜெட்களைச் சேருங்கள்"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"விட்ஜெட்களைப் பிரத்தியேகமாக்க நீண்ட நேரம் அழுத்துக"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"விட்ஜெட்களைப் பிரத்தியேகமாக்குங்கள்"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"முடக்கப்பட்ட விட்ஜெட்டுக்கான ஆப்ஸ் ஐகான்"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"நிறுவப்படும் விட்ஜெட்டுக்கான ஆப்ஸ் ஐகான்"</string>
<string name="edit_widget" msgid="9030848101135393954">"விட்ஜெட்டைத் திருத்து"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"விட்ஜெட்டைத் தேர்ந்தெடுக்கும்"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"விட்ஜெட்டை அகற்றும்"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"தேர்ந்தெடுத்த விட்ஜெட்டைக் காட்சிப்படுத்தும்"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"கீழ் இழுக்கும் மெனு"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"அறிவிப்புகள் இல்லை"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"புதிய அறிவிப்புகள் இல்லை"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"சூழல்சார் அறிவிப்புகள் இயக்கப்பட்டது"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"குறைந்த நேரத்தில் அதிக அறிவிப்பைப் பெறும்போது இரண்டு நிமிடங்கள் வரை உங்கள் சாதனம் ஒலியையும், திரையில் காட்டப்படும் பாப்-அப்களின் எண்ணிக்கையையும் குறைக்கிறது."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"முடக்கு"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"பழைய அறிவிப்பைப் பார்க்க அன்லாக் செய்க"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"மேலும் தகவல்களுக்கு தட்டவும்"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"அலாரம் எதுவுமில்லை"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"திரைப் பூட்டை உள்ளிடலாம்"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"கைரேகை சென்சாரைத் தொடவும். இது மொபைலின் பக்கவாட்டில் உள்ள சிறிய பட்டன் ஆகும்"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"கைரேகை சென்சார்"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"அங்கீகரி"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"சாதனத்தைத் திற"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ஆப்ஸால் பயன்படுத்தப்படுகிறது"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ஆப்ஸால் சமீபத்தில் பயன்படுத்தப்பட்டது"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"சிஸ்டம்"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"சிஸ்டம் கட்டுப்பாடுகள்"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"சிஸ்டம் ஆப்ஸ்"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"பல வேலைகளைச் செய்தல்"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"சமீபத்திய ஆப்ஸ்"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"திரைப் பிரிப்பு"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"உள்ளீடு"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ஆப்ஸ் ஷார்ட்கட்கள்"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"அணுகல்தன்மை"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"பின்செல்"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"பின்செல்ல, உங்கள் டச்பேடில் எங்கு வேண்டுமானாலும் இடது அல்லது வலதுபுறமாக மூன்று விரல்களால் ஸ்வைப் செய்யவும்."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"மூன்று விரல்கள் வலது மற்றும் இடதுபுறம் நகர்வதை டச்பேட் காட்டுகிறது"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"பின்செல்லும் சைகைக்கான அனிமேஷனை சாதனத்தின் திரை காட்டுகிறது"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ஹோம் கன்ட்ரோல்கள்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 4917ff6..6a91bca 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఈ స్క్రీన్షాట్ను గుర్తించింది."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఇతర ఓపెన్ యాప్లు ఈ స్క్రీన్షాట్ను గుర్తించాయి."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"గమనికకు జోడించండి"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"లింక్ను చేర్చండి"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"స్క్రీన్ రికార్డర్"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్గోయింగ్ నోటిఫికేషన్"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"మీరు <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ను రికార్డ్ చేయడం ఆపివేస్తారు"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"స్క్రీన్ను షేర్ చేస్తోంది"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"మీరు <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ను షేర్ చేయడం ఆపివేస్తారు"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"స్క్రీన్ను ప్రసారం చేస్తోంది"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"మీరు <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ను ప్రసారం చేయడం ఆపివేస్తారు"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ముఖం ద్వారా అన్లాక్ చేయబడింది. కొనసాగించడానికి నొక్కండి."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ముఖం గుర్తించబడింది. కొనసాగించడానికి నొక్కండి."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ముఖం గుర్తించబడింది. కొనసాగడానికి అన్లాక్ చిహ్నం నొక్కండి."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ముఖం ద్వారా అన్లాక్ అయింది. కొనసాగడానికి ట్యాప్ చేయండి."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ప్రామాణీకరణను రద్దు చేయండి"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"మరిన్ని ఆప్షన్లు"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"మరిన్ని విడ్జెట్లను జోడించండి"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"విడ్జెట్లను అనుకూలీకరించడానికి, నొక్కి, ఉంచండి"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"విడ్జెట్లను అనుకూలంగా మార్చండి"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"డిజేబుల్ చేయబడిన విడ్జెట్ కోసం యాప్ చిహ్నం"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ఇన్స్టాల్ చేస్తున్న విడ్జెట్ కోసం యాప్ చిహ్నం"</string>
<string name="edit_widget" msgid="9030848101135393954">"విడ్జెట్ను ఎడిట్ చేయండి"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"విడ్జెట్ను ఎంచుకోండి"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"విడ్జెట్ను తీసివేయండి"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ఎంచుకున్న విడ్జెట్ కోసం ప్లేస్ను ఎంచుకోండి"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"పుల్డౌన్ మెనూ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్లోని అన్ని యాప్లు మరియు డేటా తొలగించబడతాయి."</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించండి"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"నోటిఫికేషన్లు లేవు"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"కొత్త నోటిఫికేషన్లు ఏవీ లేవు"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"అనుకూల నోటిఫికేషన్లు ఆన్లో ఉన్నాయి"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"మీరు తక్కువ సమయంలో అనేక నోటిఫికేషన్లను స్వీకరించినప్పుడు మీ పరికరం ఇప్పుడు వాల్యూమ్ను తగ్గిస్తుంది, స్క్రీన్పై పాప్-అప్లను రెండు నిమిషాల వరకు తగ్గిస్తుంది."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ఆఫ్ చేయండి"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"పాత నోటిఫికేషన్ల కోసం అన్లాక్ చేయండి"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ఈ పరికరం మీ సంస్థకు చెందినది, కాబట్టి అది నెట్వర్క్ ట్రాఫిక్ను పర్యవేక్షించవచ్చు"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"మరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"అలారం సెట్ చేయలేదు"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"స్క్రీన్ లాక్ను ఎంటర్ చేయండి"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"వేలిముద్ర సెన్సార్ను తాకండి. ఇది ఫోన్కు పక్కన ఉండే బటన్లలో చిన్నది"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"వేలిముద్ర సెన్సార్"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ప్రామాణీకరించండి"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"పరికరాన్ని ఎంటర్ చేయండి"</string>
@@ -1302,7 +1313,7 @@
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
<string name="stylus_battery_low_percentage" msgid="2564243323894629626">"స్టయిలస్ బ్యాటరీ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"మీ స్టైలస్ను ఛార్జర్కి కనెక్ట్ చేయండి"</string>
- <string name="stylus_battery_low" msgid="7134370101603167096">"తక్కువ స్టైలస్ బ్యాటరీ"</string>
+ <string name="stylus_battery_low" msgid="7134370101603167096">"తక్కువ స్టయిలస్ బ్యాటరీ"</string>
<string name="video_camera" msgid="7654002575156149298">"వీడియో కెమెరా"</string>
<string name="call_from_work_profile_title" msgid="5418253516453177114">"వ్యక్తిగత యాప్ నుండి కాల్ చేయడం సాధ్యం కాదు"</string>
<string name="call_from_work_profile_text" msgid="2856337395968118274">"మీ సంస్థ, వర్క్ యాప్ల నుండి మాత్రమే కాల్స్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ద్వారా వినియోగంలో ఉంది"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ద్వారా ఇటీవల ఉపయోగించబడింది"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"సిస్టమ్"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"సిస్టమ్ కంట్రోల్స్"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"సిస్టమ్ యాప్లు"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"మల్టీ-టాస్కింగ్"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ఇటీవలి యాప్లు"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"స్ప్లిట్ స్క్రీన్"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ఇన్పుట్"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"యాప్ షార్ట్కట్లు"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"వెనుకకు"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"వెనుకకు వెళ్లడానికి, టచ్ప్యాడ్లో ఎక్కడైనా మూడు వేళ్లను ఉపయోగించి ఎడమ లేదా కుడికి స్వైప్ చేయండి."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"మూడు వేళ్లు కుడి, ఎడమకు కదులుతున్నట్లు చూపే టచ్ప్యాడ్"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"వెనుక సంజ్ఞ కోసం యానిమేషన్ను చూపుతున్న పరికర స్క్రీన్"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"కీబోర్డ్ బ్యాక్లైట్"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"హోమ్ కంట్రోల్స్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index f4914f0..c868b66 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ตรวจพบภาพหน้าจอนี้"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> และแอปอื่นๆ ที่เปิดอยู่ตรวจพบภาพหน้าจอนี้"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"เพิ่มลงในโน้ต"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"โปรแกรมบันทึกหน้าจอ"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"คุณจะหยุดการบันทึก <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"กำลังแชร์หน้าจอ"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"คุณจะหยุดการแชร์ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"กำลังแคสต์หน้าจอ"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"คุณจะหยุดการแคสต์ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อดำเนินการต่อ"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"จดจำใบหน้าได้ กดเพื่อดำเนินการต่อ"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ยกเลิกการตรวจสอบสิทธิ์"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ตัวเลือกเพิ่มเติม"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ฟีเจอร์ต่างๆ เช่น Quick Share และ \"หาอุปกรณ์ของฉัน\" ใช้บลูทูธ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"บลูทูธจะเปิดพรุ่งนี้เช้า"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"แชร์เสียง"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"กำลังแชร์เสียง"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"เสียง"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ชุดหูฟัง"</string>
@@ -384,7 +385,7 @@
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"บันทึกหน้าจอ"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"เริ่ม"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"หยุด"</string>
- <string name="qs_record_issue_label" msgid="8166290137285529059">"ปัญหาการบันทึก"</string>
+ <string name="qs_record_issue_label" msgid="8166290137285529059">"บันทึกปัญหา"</string>
<string name="qs_record_issue_start" msgid="2979831312582567056">"เริ่ม"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"หยุด"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"รายงานข้อบกพร่อง"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"เพิ่มวิดเจ็ตอีก"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"กดค้างเพื่อปรับแต่งวิดเจ็ต"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ปรับแต่งวิดเจ็ต"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ไอคอนแอปสำหรับวิดเจ็ตที่ปิดใช้อยู่"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ไอคอนแอปสำหรับวิดเจ็ตที่กำลังติดตั้ง"</string>
<string name="edit_widget" msgid="9030848101135393954">"แก้ไขวิดเจ็ต"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"เลือกวิดเจ็ต"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"นำวิดเจ็ตออก"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"จัดวางวิดเจ็ตที่เลือก"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"เมนูแบบเลื่อนลง"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ไม่มีการแจ้งเตือน"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ไม่มีการแจ้งเตือนใหม่"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"การแจ้งเตือนแบบปรับอัตโนมัติเปิดอยู่"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"จากนี้ไปอุปกรณ์จะลดระดับเสียงและจำนวนป๊อปอัปบนหน้าจอสูงสุด 2 นาทีเมื่อคุณได้รับการแจ้งเตือนจำนวนมากในระยะเวลาสั้นๆ"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ปิด"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ปลดล็อกเพื่อดูการแจ้งเตือนเก่า"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"อุปกรณ์นี้จัดการโดยผู้ปกครอง"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"แตะดูข้อมูลเพิ่มเติม"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ไม่มีการตั้งปลุก"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ป้อนข้อมูลการล็อกหน้าจอ"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"แตะเซ็นเซอร์ลายนิ้วมือ ซึ่งเป็นปุ่มสั้นๆ ที่อยู่ด้านข้างโทรศัพท์"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"เซ็นเซอร์ลายนิ้วมือ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ตรวจสอบสิทธิ์"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"เข้าถึงอุปกรณ์"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"ใช้อยู่โดย <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ใช้ล่าสุดโดย <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"ระบบ"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"การควบคุมระบบ"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"แอประบบ"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"การทํางานหลายอย่างพร้อมกัน"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"แอปล่าสุด"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"แยกหน้าจอ"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"อินพุต"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"แป้นพิมพ์ลัดของแอป"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ย้อนกลับ"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"หากต้องการย้อนกลับ ให้ใช้ 3 นิ้วปัดไปทางซ้ายหรือขวาที่ใดก็ได้บนทัชแพด"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ทัชแพดแสดงภาพ 3 นิ้วเลื่อนไปทางขวาและซ้าย"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"หน้าจออุปกรณ์แสดงภาพเคลื่อนไหวของท่าทางสัมผัสย้อนกลับ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ไฟแบ็กไลต์ของแป้นพิมพ์"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ระดับที่ %1$d จาก %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ระบบควบคุมอุปกรณ์สมาร์ทโฮม"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 89fa5ea..005211d 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> ang screenshot. na ito"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> at ng iba pang bukas na app ang screenshot na ito."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Idagdag sa tala"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Recorder ng Screen"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Hihinto ka sa pag-record ng <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ibinabahagi ang screen"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Hihinto ka sa pagbabahagi ng <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Kina-cast ang screen"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Hihinto ka sa pag-cast ng <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Na-unlock gamit ang mukha. Pindutin para magpatuloy."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nakilala ang mukha. Pindutin para magpatuloy."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nakilala ang mukha. Pindutin ang unlock para magpatuloy."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselahin ang Pag-authenticate"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Higit Pang Opsyon"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Gumagamit ng Bluetooth ang mga feature tulad ng Quick Share at Hanapin ang Aking Device"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Mag-o-on ang Bluetooth bukas ng umaga"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Ibahagi ang audio"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Ibinabahagi ang audio"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> na baterya"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Magdagdag ng higit pang widget"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pindutin nang matagal para i-customize ang mga widget"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"I-customize ang mga widget"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icon ng app para sa na-disable na widget"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ini-install ang icon ng app para sa isang widget"</string>
<string name="edit_widget" msgid="9030848101135393954">"I-edit ang widget"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pumili ng widget"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alisin ang widget"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ilagay ang napiling widget"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Walang mga notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Walang bagong notification"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"On ang adaptive notifications"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Hinihinaan ng device ang volume at binabawasan nito ang pop-ups nang hanggang 2 minuto kapag nakatanggap ng maraming notification sa maikling oras."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"I-off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"I-unlock para makita ang mga mas lumang notification"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Pinapamahalaan ng magulang mo itong device"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Pagmamay-ari ng organisasyon mo ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"I-tap para sa higit pang impormasyon"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Walang alarm"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ilagay ang lock ng screen"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Pindutin ang sensor para sa fingerprint. Ito ang mas maikling button sa gilid ng telepono"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor para sa fingerprint"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"i-authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ilagay ang device"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Ginagamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kamakailang ginamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Mga kontrol ng system"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Mga system app"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Pag-multitask"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Kamakailang mga app"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Mga shortcut ng app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Bumalik"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para bumalik, mag-swipe pakaliwa o pakanan gamit ang tatlong daliri kahit saan sa touchpad."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad na nagpapakita ng tatlong daliring gumagalaw pakanan at pakaliwa"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Screen ng device na nagpapakita ng animation para sa galaw sa pagbalik"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Backlight ng keyboard"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d sa %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Mga Home Control"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index bf6e6aa..f468d5d 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu ekran görüntüsünü algıladı."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ve diğer açık uygulamalar bu ekran görüntüsünü algıladı."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Nota ekle"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Ekran Kaydedicisi"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> içeriğini kaydetmeyi durdurursunuz"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılıyor"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> içeriğini paylaşmayı durdurursunuz"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekran yayınlanıyor"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> içeriğini yayınlamayı durdurursunuz"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Cihazın kilidini yüzünüzle açtınız. Devam etmek için basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yüzünüz tanındı. Devam etmek için basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kimlik doğrulamayı iptal et"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Diğer Seçenekler"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ve Cihazımı Bul gibi özellikler Bluetooth\'u kullanır"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth yarın sabah açılacak"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sesi paylaş"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Ses paylaşılıyor"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ses"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Mikrofonlu kulaklık"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Daha fazla widget ekle"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widget\'ları özelleştirmek için uzun basın"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widget\'ları özelleştir"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Devre dışı bırakılan widget\'ın uygulama simgesi"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Yüklenmeye devam eden bir widget\'ın uygulama simgesi"</string>
<string name="edit_widget" msgid="9030848101135393954">"Widget\'ı düzenle"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"widget seçin"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"widget\'ı kaldır"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilen widget\'ı yerleştir"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"açılır menü"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirim yok"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildirim yok"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Uyarlanabilir bildirimler açık"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Cihazınız, kısa süre içinde çok sayıda bildirim aldığınızda artık iki dakika boyunca sesi kısar ve ekrandaki pop-up\'ları azaltır."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Kapat"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eski bildirimler için kilidi açın"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz ebeveyniniz tarafından yönetiliyor"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu cihaz, kuruluşunuza ait olup ağ trafiği kuruluşunuz tarafından izlenebilir"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Daha fazla bilgi için dokunun"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm yok"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ekran kilidini gir"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Parmak izi sensörüne dokunun. Sensör, telefonun yan tarafındaki daha kısa olan düğmedir."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Parmak izi sensörü"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"kimlik doğrulaması yapın"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz girin"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) tarafından kullanılıyor"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"En son <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) tarafından kullanıldı"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistem kontrolleri"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistem uygulamaları"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Çoklu görev becerisi"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Son uygulamalar"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Bölünmüş ekran"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Giriş"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Uygulama kısayolları"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri dön"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Geri dönmek için dokunmatik alanın herhangi bir yerinde üç parmağınızla sola veya sağa kaydırın."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sağa ve sola hareket eden üç parmağın gösterildiği dokunmatik alan"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Geri hareketi animasyonunu gösteren cihaz ekranı"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klavye aydınlatması"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Seviye %1$d / %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ev Kontrolleri"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 6206289..c13aac7 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"Додаток <xliff:g id="APPNAME">%1$s</xliff:g> виявив цей знімок екрана."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> та інші відкриті додатки виявили цей знімок екрана."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додати до примітки"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Запис відео з екрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
@@ -129,24 +131,25 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ви зупините запис контенту з додатка <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <!-- no translation found for share_to_app_chip_accessibility_label (4210256229976947065) -->
+ <skip />
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ви зупините надсилання контенту з додатка <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <!-- no translation found for cast_to_other_device_chip_accessibility_label (1680650146639059938) -->
+ <skip />
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ви зупините трансляцію контенту з додатка <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +198,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейс-контроль). Натисніть, щоб продовжити."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Обличчя розпізнано. Натисніть, щоб продовжити."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасувати автентифікацію"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Інші опції"</string>
@@ -309,10 +314,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Такі функції, як швидкий обмін і \"Знайти пристрій\", використовують Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth увімкнеться завтра вранці"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Поділитись аудіо"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Надсилання аудіо"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> заряду акумулятора"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудіопристрій"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнітура"</string>
@@ -477,6 +480,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додати більше віджетів"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Утримуйте, щоб налаштувати віджети"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Налаштувати віджети"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок додатка для вимкненого віджета"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок додатка для віджета, що встановлюється"</string>
<string name="edit_widget" msgid="9030848101135393954">"Редагувати віджет"</string>
@@ -495,6 +500,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виберіть віджет"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"видалити віджет"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"розмістити вибраний віджет"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"спадне меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string>
@@ -548,6 +559,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Сповіщень немає"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Немає нових сповіщень"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивні сповіщення ввімкнено"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Пристрій знижує гучність і зменшує кількість спливаючих вікон на екрані на період до двох хвилин, коли ви отримуєте багато сповіщень за короткий час."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Вимкнути"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Розблокуйте, щоб переглянути старіші"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Цим пристроєм керує батько або мати"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Цей пристрій належить вашій організації. Її адміністратор може відстежувати мережевий трафік"</string>
@@ -1203,8 +1217,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Натисніть, щоб дізнатися більше"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Немає будильників"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"показати способи розблокування екрана"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Торкніться сканера відбитків пальців. Це менша кнопка на бічній панелі телефона."</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер відбитків пальців"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"пройти автентифікацію"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"відкрити пристрій"</string>
@@ -1346,7 +1359,15 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Використовується додатком <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Нещодавно використано (<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+ <!-- no translation found for shortcut_helper_category_system_controls (3153344561395751020) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_category_system_apps (6001757545472556810) -->
+ <skip />
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Багатозадачність"</string>
+ <!-- no translation found for shortcutHelper_category_recent_apps (7918731953612377145) -->
+ <skip />
+ <!-- no translation found for shortcutHelper_category_split_screen (1159669813444812244) -->
+ <skip />
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Введення"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Комбінації клавіш для додатків"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
@@ -1363,6 +1384,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Щоб перейти назад, проведіть трьома пальцями вліво або вправо по сенсорній панелі."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Сенсорна панель із зображенням трьох пальців, що рухаються вправо й уліво"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екран пристрою, на якому показано анімацію щодо жесту \"Назад\""</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Підсвічування клавіатури"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Рівень %1$d з %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Автоматизація дому"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 0aab4ce..9c6df90 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> اور دیگر کھلی ایپس نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"نوٹ میں شامل کریں"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"اسکرین ریکارڈر"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"آپ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> کو ریکارڈ نہیں کر پائیں گے"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"اسکرین کا اشتراک ہو رہا ہے"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"آپ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> کا اشتراک نہیں کر پائیں گے"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"اسکرین کاسٹ ہو رہی ہے"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"آپ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> کو کاسٹ نہیں کر پائیں گے"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کے لیے دبائیں۔"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کے لیے دبائیں۔"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"تصدیق کردہ"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"تصدیق کو منسوخ کریں"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزید اختیارات"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"مزید ویجٹس شامل کریں"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ویجٹس کو حسب ضرورت بنانے کے لیے لانگ پریس کریں"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ویجیٹس کو حسب ضرورت بنائیں"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"غیر فعال ویجیٹ کے لئے ایپ آئیکن"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"انسٹال ہونے والے ویجیٹ کا ایپ آئیکن"</string>
<string name="edit_widget" msgid="9030848101135393954">"ویجیٹ میں ترمیم کریں"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ویجیٹ منتخب کریں"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ویجیٹ ہٹائیں"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"منتخب ویجیٹ رکھیں"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"پل ڈاؤن مینیو"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"کوئی اطلاعات نہیں ہیں"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"کوئی نئی اطلاعات نہیں"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"تغیر پذیر اطلاعات آن ہیں"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"کم وقت میں متعدد اطلاعات ملنے پر آپ کا آلہ اب دو منٹ تک سکرین پر والیوم اور پوپ اپس کم کر دیتا ہے۔"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"آف کریں"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"پرانی اطلاعات دیکھنے کیلئے غیر مقفل کریں"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"یہ آلہ آپ کے والدین کے زیر انتظام ہے"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"آپ کی تنظیم اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
@@ -1205,8 +1219,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"کوئی الارم سیٹ نہیں ہے"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"اسکرین لاک درج کریں"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"فنگر پرنٹ سینسر کو ٹچ کریں۔ یہ فون کے سائیڈ میں چھوٹا سا بٹن ہے۔"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"فنگر پرنٹ سینسر"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"تصدیق کریں"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"آلہ درج کریں"</string>
@@ -1348,7 +1361,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) کے زیر استعمال"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) کے ذریعے حال ہی میں استعمال کیا گیا"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"سسٹم"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"سسٹم کنٹرولز"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"سسٹم ایپس"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ملٹی ٹاسکنگ"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"حالیہ ایپس"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"اسپلٹ اسکرین"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"ان پٹ"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ایپ شارٹ کٹس"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
@@ -1365,6 +1382,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"واپس جائیں"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"واپس جانے کے لیے، ٹچ پیڈ پر کہیں بھی تین انگلیوں کی مدد سے دائیں یا بائیں سوائپ کریں۔"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ٹچ پیڈ دائیں اور بائیں حرکت کرتی ہوئی تین انگلیاں دکھا رہا ہے"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"آلہ کی اسکرین پیچھے جانے کے اشارے کے لیے اینیمیشن دکھا رہی ہے"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"کی بورڈ بیک لائٹ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d میں سے %1$d کا لیول"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ہوم کنٹرولز"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 312737d..1e55f29 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> skrinshot olinganini aniqladi."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> va boshqa ochiq ilovalar skrinshot olinganini aniqladi."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qaydga qoʻshish"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"Havolani kiritish"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"Ekranni yozib olish"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> yozib olinishini toʻxtatasiz"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran ulashilmoqda"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ulashuvini toʻxtatasiz"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekran namoyish qilinmoqda"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> translatsiyasini toʻxtatasiz"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Yuz orqali ochildi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yuz aniqlandi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yuz aniqlandi. Davom etish uchun ochish belgisini bosing."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Yuz bilan ochildi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Autentifikatsiyani bekor qilish"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Boshqa parametrlar"</string>
@@ -309,10 +310,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tezkor ulashuv va Qurilmamni top kabi funksiyalar Bluetooth ishlatadi"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ertaga ertalab yoqiladi"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audioni ulashish"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio ulashuvi yoniq"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Garnitura"</string>
@@ -477,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Koʻproq vidjetlar qoʻshish"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vidjetlarni sozlash uchun bosib turing"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidjetlarni moslashtirish"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Faolsizlantirilgan vidjet uchun ilova belgisi"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Oʻrnatilayotgan vidjet uchun ilova belgisi"</string>
<string name="edit_widget" msgid="9030848101135393954">"Vidjetni tahrirlash"</string>
@@ -495,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidjet tanlash"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidjetni olib tashlash"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"tanlangan vidjetni joylash"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
@@ -548,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirishnomalar yo‘q"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yangi bildirishoma yoʻq"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptiv bildirishnomalar yoniq"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Qisqa vaqt oraligʻida koʻp bildirishnoma kelsa, qurilmadagi tovush balandligi hamda bildirgi oynalar soni ikki daqiqagacha kamaytiriladi."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Faolsizlantirish"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eskilarini koʻrish uchun qulfni yeching"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu qurilmani ota-onangiz boshqaradi"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu qurilma tashkilotingizga tegishli va tarmoq trafigi tashkilotingiz tomonidan kuzatilishi mumkin"</string>
@@ -1203,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Batafsil axborot olish uchun bosing"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Signal sozlanmagan"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"ekran qulfini kiriting"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Barmoq izi skaneriga tegining. Bu – telefonning yon tomonidagi qisqa tugma"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Barmoq izi skaneri"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatsiya"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"qurilmani ochish"</string>
@@ -1346,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ishlatmoqda"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Yaqinda <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ishlatgan"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Tizim"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Tizim boshqaruvi tugmalari"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Tizim ilovalari"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multi-vazifalilik"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Oxirgi ilovalar"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekranni ikkiga ajratish"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Kiritish"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ilova yorliqlari"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
@@ -1363,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Orqaga qaytish"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ortga qaytish uchun sensorli panelda uchta barmoqni chapga yoki oʻngga suring."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sensorli panelda uchta barmoq chapga va oʻngga harakatlanishi"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Qurilma ekranidagi ortga qaytish ishorasi animatsiyasi"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura orqa yoritkichi"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Daraja: %1$d / %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Uy boshqaruvi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f578e14a..f52b831 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> đã phát hiện thấy ảnh chụp màn hình này."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> và các ứng dụng đang mở khác đã phát hiện thấy ảnh chụp màn hình này."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Thêm vào ghi chú"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Trình ghi màn hình"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Bạn sẽ dừng ghi âm nội dung của <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Đang chia sẻ màn hình"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Bạn sẽ dừng chia sẻ nội dung của <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Đang truyền màn hình"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Bạn sẽ dừng truyền nội dung của <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Đã mở khoá bằng khuôn mặt. Hãy nhấn để tiếp tục."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Đã nhận diện khuôn mặt. Hãy nhấn để tiếp tục."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Huỷ quy trình xác thực"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Tuỳ chọn khác"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Các tính năng như Chia sẻ nhanh và Tìm thiết bị của tôi đều sử dụng Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sẽ bật vào sáng mai"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Chia sẻ âm thanh"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Đang chia sẻ âm thanh"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> pin"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Âm thanh"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Tai nghe"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Thêm tiện ích khác"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nhấn và giữ để tuỳ chỉnh tiện ích"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tuỳ chỉnh tiện ích"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Biểu tượng ứng dụng của tiện ích đã bị vô hiệu hoá"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Đang cài đặt biểu tượng ứng dụng của một tiện ích"</string>
<string name="edit_widget" msgid="9030848101135393954">"Chỉnh sửa tiện ích"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chọn tiện ích"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"xoá tiện ích"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"đặt tiện ích đã chọn vào vị trí"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Chuyển đổi người dùng"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"trình đơn kéo xuống"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Không có thông báo mới"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Thông báo thích ứng đang bật"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Giờ đây, thiết bị sẽ giảm âm lượng và giảm số cửa sổ bật lên trên màn hình trong tối đa 2 phút khi bạn nhận được nhiều thông báo trong một khoảng thời gian ngắn."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Tắt"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Mở khoá để xem thông báo cũ"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Thiết bị này do cha mẹ của bạn quản lý"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tổ chức của bạn sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
@@ -786,7 +798,7 @@
<string name="keyboard_shortcut_join" msgid="3578314570034512676">"hoặc"</string>
<string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Xoá cụm từ tìm kiếm"</string>
<string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"Phím tắt"</string>
- <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Lối tắt tìm kiếm"</string>
+ <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Tìm lối tắt"</string>
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Không tìm thấy lối tắt"</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Hệ thống"</string>
<string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Đầu vào"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Nhấn để biết thêm thông tin"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Chưa đặt chuông báo"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"nhập phương thức mở khoá màn hình"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Hãy chạm vào cảm biến vân tay. Đó là nút ngắn ở cạnh bên của điện thoại"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Cảm biến vân tay"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"xác thực"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"truy cập thiết bị"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đang dùng"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đã dùng gần đây"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Hệ thống"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Cài đặt hệ thống"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Ứng dụng hệ thống"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Đa nhiệm"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ứng dụng gần đây"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Chia đôi màn hình"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Phương thức nhập"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Lối tắt ứng dụng"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Quay lại"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Để quay lại, hãy vuốt sang trái hoặc sang phải bằng 3 ngón tay ở vị trí bất kỳ trên bàn di chuột."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Minh hoạ thao tác di chuyển sang phải và sang trái bằng 3 ngón tay trên bàn di chuột"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Màn hình thiết bị hiện ảnh động minh hoạ cử chỉ quay lại"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Đèn nền bàn phím"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Độ sáng %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Điều khiển nhà"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index ae1f2b0..6a5d4be 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 检测到此屏幕截图。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 及其他打开的应用检测到此屏幕截图。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"添加到备注中"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"屏幕录制器"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"将停止录制<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>的内容"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在共享屏幕"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"将停止分享<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>的内容"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"正在投放屏幕"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"将停止投放<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>的内容"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已通过面孔识别解锁。点按即可继续。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"识别出面孔。点按即可继续。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"识别出面孔。按下解锁图标即可继续。"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已经过身份验证"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消身份验证"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多选项"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"添加更多微件"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"长按即可自定义微件"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自定义微件"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用微件的应用图标"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"代表正在安装的微件的应用图标"</string>
<string name="edit_widget" msgid="9030848101135393954">"修改微件"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"选择微件"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除微件"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所选微件"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉菜单"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"没有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"没有新通知"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"自适应通知功能已开启"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"现在,当在短时间内收到许多通知时,您的设备会调低音量并减少屏幕上的弹出式窗口,最多持续两分钟。"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"关闭"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解锁即可查看旧通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此设备由您的家长管理"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"贵单位拥有此设备,且可能会监控网络流量"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"点按即可了解详情"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未设置闹钟"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"输入屏幕解锁信息"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"请轻触指纹传感器,即手机侧面较短的那个按钮"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指纹传感器"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"身份验证"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"进入设备"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正在使用(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”最近使用过(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"系统"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系统控件"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系统应用"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多任务处理"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近用过的应用"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分屏"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"输入"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"应用快捷键"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"如要返回,请使用三根手指在触控板上的任意位置左滑或右滑。"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"触控板,其中显示了三根手指右移和左移"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"设备屏幕,其中显示了返回手势的动画"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"键盘背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 级,共 %2$d 级"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"家居控制"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 9467b9b..0446a1b 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -188,7 +188,7 @@
</string-array>
<string-array name="tile_states_hearing_devices">
<item msgid="1235334096484287173">"不可用"</item>
- <item msgid="3079622119444911877">"关闭"</item>
- <item msgid="3028994095749238254">"开启"</item>
+ <item msgid="3079622119444911877">"已关闭"</item>
+ <item msgid="3028994095749238254">"已开启"</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 35087f3..1e316e7 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -103,6 +103,7 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 偵測到此螢幕截圖。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 和其他開啟的應用程式偵測到此螢幕截圖。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至筆記"</string>
+ <string name="backlinks_include_link" msgid="4562093591148248158">"加入連結"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"螢幕錄影機"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string>
@@ -129,24 +130,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"你將停止錄影「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享螢幕"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"你將停止分享「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"正在投放螢幕"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"你將停止投放「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +195,7 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已使用面孔解鎖。按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"已識別面孔。按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"已使用面孔解鎖,輕按即可繼續。"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
@@ -475,6 +476,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用小工具的應用程式圖示"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"此應用程式圖示用來表示安裝中的小工具"</string>
<string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string>
@@ -493,6 +496,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"揀小工具"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
@@ -546,6 +555,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"已啟用自動調節通知"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"現在每當你於短時間內收到大量通知,裝置便會調低音量並減少螢幕上的彈出式視窗最多兩分鐘。"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由你的家長管理"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"你的機構擁有此裝置,並可能會監察網絡流量"</string>
@@ -1201,8 +1213,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕按即可瞭解詳情"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"輸入螢幕鎖定憑證"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"輕輕掂下指紋感應器,即係手機側邊短啲嗰粒掣"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指紋感應器"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"驗證"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string>
@@ -1344,7 +1355,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> 正在使用 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近使用過此權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"系統"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系統控制項"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系統應用程式"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多工處理"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使用的應用程式"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割螢幕"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"輸入"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"應用程式捷徑"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
@@ -1361,6 +1376,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"用三隻手指在觸控板上任何一處左右滑動即可返回。"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"觸控板上有三隻手指左右移動"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"裝置畫面顯示返回手勢動畫"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"智能家居"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 51fe3d7..fa1136f 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"「<xliff:g id="APPNAME">%1$s</xliff:g>」偵測到這張螢幕截圖。"</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"「<xliff:g id="APPNAME">%1$s</xliff:g>」和其他開啟的應用程式偵測到這張螢幕截圖。"</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至記事本"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"螢幕錄影器"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"系統將停止錄製「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」的內容"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享畫面"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"系統將停止分享「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」的內容"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"正在投放畫面"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"系統將停止投放「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」的內容"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"裝置已透過你的臉解鎖,按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"臉孔辨識完成,按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"臉孔辨識完成,按下「解鎖」圖示即可繼續操作。"</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已通過驗證"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
@@ -386,7 +389,7 @@
<string name="qs_record_issue_start" msgid="2979831312582567056">"開始"</string>
<string name="qs_record_issue_stop" msgid="3531747965741982657">"停止"</string>
<string name="qs_record_issue_bug_report" msgid="8229031766918650079">"錯誤報告"</string>
- <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"哪些裝置使用體驗受到影響?"</string>
+ <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"哪方面的裝置使用體驗受到影響?"</string>
<string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"選取問題類型"</string>
<string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"螢幕錄影"</string>
<string name="performance" msgid="6552785217174378320">"效能"</string>
@@ -475,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"所停用小工具的應用程式圖示"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"這個應用程式圖示用來表示安裝中的小工具"</string>
<string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string>
@@ -493,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"選取小工具"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會刪除。"</string>
@@ -546,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"自動調整通知功能已開啟"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"如果在短時間內收到多則通知,裝置會在最長兩分鐘內調降音量,並減少在畫面上顯示彈出式視窗。"</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"這個裝置是由你的家長管理"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"貴機構擁有這部裝置,而且可能會監控網路流量"</string>
@@ -819,7 +833,7 @@
<string name="input_switch_input_language_next" msgid="3782155659868227855">"切換到下一個語言"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換到上一個語言"</string>
<string name="input_access_emoji" msgid="8105642858900406351">"存取表情符號"</string>
- <string name="input_access_voice_typing" msgid="7291201476395326141">"存取語音輸入內容"</string>
+ <string name="input_access_voice_typing" msgid="7291201476395326141">"使用語音輸入功能"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"應用程式"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google 助理"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"瀏覽器"</string>
@@ -1201,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕觸即可瞭解詳情"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"輸入螢幕鎖定憑證"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"請輕觸指紋感應器,也就是手機側邊較短的按鈕"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指紋感應器"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"驗證"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string>
@@ -1344,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"正由「<xliff:g id="APP_NAME">%1$s</xliff:g>」使用 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近用過這項權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"系統"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系統控制選項"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系統應用程式"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多工處理"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使用的應用程式"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割畫面"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"輸入"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"應用程式捷徑"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
@@ -1361,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"如要返回,請用三指在觸控板上向左或右滑動。"</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"動畫顯示三指正在觸控板上向左右移動"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"裝置畫面顯示返回手勢的動畫"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"居家控制"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 7b39f16..e9e7239 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -103,6 +103,8 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"I-<xliff:g id="APPNAME">%1$s</xliff:g> ithole lesi sithombe-skrini."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"I-<xliff:g id="APPNAME">%1$s</xliff:g> namanye ama-app avuliwe athole lesi sithombe-skrini."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engeza kunothi"</string>
+ <!-- no translation found for backlinks_include_link (4562093591148248158) -->
+ <skip />
<string name="screenrecord_title" msgid="4257171601439507792">"Okokuqopha iskrini"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
@@ -129,24 +131,23 @@
<skip />
<!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
<skip />
- <!-- no translation found for screenrecord_stop_dialog_message_specific_app (5285148796772616326) -->
- <skip />
+ <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Uzoyeka ukurekhoda <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
<skip />
+ <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Yabelana ngesikrini"</string>
<!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
<skip />
<!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
<skip />
- <!-- no translation found for share_to_app_stop_dialog_message_specific_app (124371406810544777) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Uzoyeka ukwaba <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
<skip />
+ <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Isikrini sokusakaza"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
<skip />
<!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
<skip />
- <!-- no translation found for cast_to_other_device_stop_dialog_message_specific_app (4891536209254041850) -->
- <skip />
+ <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Uzoyeka ukusakaza <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
<!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
<skip />
<!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -195,6 +196,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Vula ngobuso. Cindezela ukuze uqhubeke."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ubuso buyaziwa. Cindezela ukuze uqhubeke."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face_sfps (2499213248903257928) -->
+ <skip />
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
<string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Khansela Ukuqinisekisa"</string>
<string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Okukhethwayo Okwengeziwe"</string>
@@ -309,10 +312,8 @@
<skip />
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Izakhi ezifana nokuthi Ukwabelana Ngokushesha kanye nokuthi Thola Idivayisi Yami zisebenzisa i-Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"IBluetooth izovuleka kusasa ekuseni"</string>
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
- <skip />
- <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
- <skip />
+ <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Yabelana ngomsindo"</string>
+ <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Yabelana ngomsindo"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ibhethri"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Umsindo"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ihedisethi"</string>
@@ -477,6 +478,8 @@
<string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engeza amawijethi engeziwe"</string>
<string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Cindezela isikhathi eside ukuze wenze ngokwezifiso amawijethi"</string>
<string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Yenza ngokwezifiso amawijethi"</string>
+ <!-- no translation found for unlock_reason_to_customize_widgets (5011909432460546033) -->
+ <skip />
<string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Isithonjana se-app sewijethi evaliwe"</string>
<string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Isithonjana se-app sewijethi siyafakwa"</string>
<string name="edit_widget" msgid="9030848101135393954">"Hlela amawijethi"</string>
@@ -495,6 +498,12 @@
<string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"khetha iwijethi"</string>
<string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"susa iwijethi"</string>
<string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"beka iwijethi ekhethiwe"</string>
+ <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+ <skip />
+ <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+ <skip />
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Shintsha umsebenzisi"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"imenyu yokudonsela phansi"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wonke ama-app nedatha kulesi sikhathi azosuswa."</string>
@@ -548,6 +557,9 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Azikho izaziso"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Azikho izaziso ezintsha"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Izaziso zokuzijwayeza zivuliwe"</string>
+ <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Idivayisi yakho manje yehlisa ivolumu futhi yehlisa okwesikhashana esikrinini kuze kufike emizuzwini emibili lapho uthola izaziso eziningi ngesikhathi esifushane."</string>
+ <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vala"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vula ukuze ubone izaziso ezindala"</string>
<string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Le divayisi iphethwe ngumzali wakho"</string>
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Inhlangano yakho ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
@@ -1203,8 +1215,7 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Thepha ukuze uthole olunye ulwazi"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Akukho alamu esethiwe"</string>
<string name="accessibility_bouncer" msgid="5896923685673320070">"faka ukukhiya isikrini"</string>
- <!-- no translation found for accessibility_side_fingerprint_indicator_label (1673807833352363712) -->
- <skip />
+ <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Thinta inzwa yesigxivizo somunwe Inkinobho emfushane ehlangothini lwefoni"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Inzwa yesigxivizo somunwe"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"gunyaza"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"faka idivayisi"</string>
@@ -1346,7 +1357,11 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Isetshenziswa yi-<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kusetshenziswe kamuva yi-<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Isistimu"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Izilawuli zesistimu"</string>
+ <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Ama-app esistimu"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Ukwenza imisebenzi eminingi"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ama-app wakamuva"</string>
+ <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Hlukanisa isikrini"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Okokufaka"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Izinqamuleli Zohlelo lokusebenza"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
@@ -1363,6 +1378,10 @@
<skip />
<!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
<skip />
+ <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Buyela emuva"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ukuze ubuyele emuva, swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu noma yikuphi ephedini yokuthinta."</string>
+ <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Iphedi yokuthinta ebonisa iminwe emithathu iya kwesokudla nakwesokunxele"</string>
+ <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Isikrini sedivayisi esibonisa opopayi bokuthinta kwasemuva"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Ilambu lekhibhodi"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ileveli %1$d ka-%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Izilawuli Zasekhaya"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index b3d3021..0350cd7 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -236,11 +236,8 @@
<!-- Internet Dialog -->
<!-- Material next state on color-->
<color name="settingslib_state_on_color">@color/settingslib_state_on</color>
- <!-- Material next track on color-->
- <color name="settingslib_track_on_color">@color/settingslib_track_on</color>
<!-- Material next track off color-->
<color name="settingslib_track_off_color">@color/settingslib_track_off</color>
- <color name="connected_network_primary_color">#191C18</color>
<color name="connected_network_secondary_color">#41493D</color>
<color name="dream_overlay_camera_mic_off_dot_color">#FCBE03</color>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 177ba598..212dae2 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -233,6 +233,7 @@
<item type="id" name="smart_space_barrier_bottom" />
<item type="id" name="small_clock_guideline_top" />
<item type="id" name="weather_clock_date_and_icons_barrier_bottom" />
+ <item type="id" name="weather_clock_bc_smartspace_bottom" />
<item type="id" name="accessibility_actions_view" />
<!-- Privacy dialog -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f533cb8..e92b942 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -269,8 +269,7 @@
<string name="screenshot_detected_multiple_template"><xliff:g id="appName" example="Google Chrome">%1$s</xliff:g> and other open apps detected this screenshot.</string>
<!-- Add to note button used in App Clips flow to return the saved screenshot image to notes app. [CHAR LIMIT=NONE] -->
<string name="app_clips_save_add_to_note">Add to note</string>
- <!-- TODO(b/300307759): Temporary string for text view that displays backlinks data. [CHAR LIMIT=NONE] -->
- <string name="backlinks_string" translatable="false">Open <xliff:g id="appName" example="Google Chrome">%1$s</xliff:g></string>
+ <string name="backlinks_include_link">Include link</string>
<!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
<string name="screenrecord_title">Screen Recorder</string>
@@ -330,6 +329,8 @@
<!-- Button to stop a screen recording [CHAR LIMIT=35] -->
<string name="screenrecord_stop_dialog_button">Stop recording</string>
+ <!-- Content description for the status bar chip shown to the user when they're sharing their screen to another app on the device [CHAR LIMIT=NONE] -->
+ <string name="share_to_app_chip_accessibility_label">Sharing screen</string>
<!-- Title for a dialog shown to the user that will let them stop sharing their screen to another app on the device [CHAR LIMIT=50] -->
<string name="share_to_app_stop_dialog_title">Stop sharing screen?</string>
<!-- Text telling a user that they will stop sharing their screen if they click the "Stop sharing" button [CHAR LIMIT=100] -->
@@ -339,6 +340,8 @@
<!-- Button to stop screen sharing [CHAR LIMIT=35] -->
<string name="share_to_app_stop_dialog_button">Stop sharing</string>
+ <!-- Content description for the status bar chip shown to the user when they're casting their screen to a different device [CHAR LIMIT=NONE] -->
+ <string name="cast_to_other_device_chip_accessibility_label">Casting screen</string>
<!-- Title for a dialog shown to the user that will let them stop casting their screen to a different device [CHAR LIMIT=50] -->
<string name="cast_to_other_device_stop_dialog_title">Stop casting screen?</string>
<!-- Text telling a user that they will stop casting their screen to a different device if they click the "Stop casting" button [CHAR LIMIT=100] -->
@@ -443,6 +446,8 @@
<string name="biometric_dialog_tap_confirm_with_face_alt_2">Face recognized. Press to continue.</string>
<!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
<string name="biometric_dialog_tap_confirm_with_face_alt_3">Face recognized. Press the unlock icon to continue.</string>
+ <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication with SFPS [CHAR LIMIT=60]-->
+ <string name="biometric_dialog_tap_confirm_with_face_sfps">Unlocked by face. Tap to continue.</string>
<!-- Talkback string when a biometric is authenticated [CHAR LIMIT=NONE] -->
<string name="biometric_dialog_authenticated">Authenticated</string>
<!-- Talkback string when a canceling authentication [CHAR LIMIT=NONE] -->
@@ -1188,6 +1193,8 @@
<string name="popup_on_dismiss_cta_tile_text">Long press to customize widgets</string>
<!-- Text for the button to configure widgets after long press. [CHAR LIMIT=50] -->
<string name="button_to_configure_widgets_text">Customize widgets</string>
+ <!-- Text for unlock reason on the bouncer before customizing widgets. [CHAR LIMIT=NONE] -->
+ <string name="unlock_reason_to_customize_widgets">Unlock to customize widgets</string>
<!-- Description for the App icon of disabled widget. [CHAR LIMIT=NONE] -->
<string name="icon_description_for_disabled_widget">App icon for disabled widget</string>
<!-- Description for the App icon of a package that is currently being installed. [CHAR LIMIT=NONE] -->
@@ -1388,7 +1395,7 @@
<!-- Text which is shown in the expanded notification shade when there are currently no notifications visible that the user hasn't already seen. [CHAR LIMIT=30] -->
<string name="no_unseen_notif_text">No new notifications</string>
- <!-- Title of heads up notification for adaptive notifications user education. [CHAR LIMIT=30] -->
+ <!-- Title of heads up notification for adaptive notifications user education. [CHAR LIMIT=50] -->
<string name="adaptive_notification_edu_hun_title">Adaptive notifications is on</string>
<!-- Text of heads up notification for adaptive notifications user education. [CHAR LIMIT=100] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 73b7586..7475eb2 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1315,7 +1315,7 @@
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>
- <style name="MainSwitch.Settingslib" parent="@android:style/Theme.DeviceDefault">
+ <style name="MainSwitch.Settingslib" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="android:switchMinWidth">@dimen/settingslib_min_switch_width</item>
</style>
@@ -1358,6 +1358,7 @@
<style name="InternetDialog.NetworkTitle.Active">
<item name="android:textAppearance">@style/TextAppearance.InternetDialog.Active</item>
+ <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
</style>
<style name="InternetDialog.NetworkSummary">
@@ -1370,18 +1371,19 @@
<style name="InternetDialog.NetworkSummary.Active">
<item name="android:textAppearance">@style/TextAppearance.InternetDialog.Secondary.Active
</item>
+ <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
</style>
<style name="TextAppearance.InternetDialog">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textSize">16sp</item>
- <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
<item name="android:textDirection">locale</item>
</style>
<style name="TextAppearance.InternetDialog.Secondary">
<item name="android:textSize">14sp</item>
- <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
</style>
<style name="TextAppearance.InternetDialog.Active"/>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
index d5bc10a..c00007b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
@@ -22,7 +22,7 @@
import android.view.MotionEvent;
import com.android.systemui.shared.recents.ISystemUiProxy;
-// Next ID: 29
+// Next ID: 34
oneway interface IOverviewProxy {
void onActiveNavBarRegionChanges(in Region activeRegion) = 11;
@@ -83,6 +83,11 @@
void onSystemBarAttributesChanged(int displayId, int behavior) = 20;
/**
+ * Sent when {@link TaskbarDelegate#onTransitionModeUpdated} is called.
+ */
+ void onTransitionModeUpdated(int barMode, boolean checkBarModes) = 21;
+
+ /**
* Sent when the desired dark intensity of the nav buttons has changed
*/
void onNavButtonsDarkIntensityChanged(float darkIntensity) = 22;
@@ -101,4 +106,30 @@
* Sent when the task bar stash state is toggled.
*/
void onTaskbarToggled() = 27;
+
+ /**
+ * Sent when the wallpaper visibility is updated.
+ */
+ void updateWallpaperVisibility(int displayId, boolean visible) = 29;
+
+ /**
+ * Sent when {@link TaskbarDelegate#checkNavBarModes} is called.
+ */
+ void checkNavBarModes() = 30;
+
+ /**
+ * Sent when {@link TaskbarDelegate#finishBarAnimations} is called.
+ */
+ void finishBarAnimations() = 31;
+
+ /**
+ * Sent when {@link TaskbarDelegate#touchAutoDim} is called. {@param reset} is true, when auto
+ * dim is reset after a timeout.
+ */
+ void touchAutoDim(boolean reset) = 32;
+
+ /**
+ * Sent when {@link TaskbarDelegate#transitionTo} is called.
+ */
+ void transitionTo(int barMode, boolean animate) = 33;
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
index 3cb5bc7..ea73216 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
@@ -10,7 +10,6 @@
import android.graphics.RectF;
import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.wm.shell.util.SplitBounds;
/**
* Utility class to position the thumbnail in the TaskView
@@ -35,8 +34,6 @@
private final Matrix mMatrix = new Matrix();
private boolean mIsOrientationChanged;
- private SplitBounds mSplitBounds;
- private int mDesiredStagePosition;
public Matrix getMatrix() {
return mMatrix;
@@ -50,11 +47,6 @@
return mIsOrientationChanged;
}
- public void setSplitBounds(SplitBounds splitBounds, int desiredStagePosition) {
- mSplitBounds = splitBounds;
- mDesiredStagePosition = desiredStagePosition;
- }
-
/**
* Updates the matrix based on the provided parameters
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/shared/src/com/android/systemui/shared/statusbar/phone/BarTransitions.java
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
rename to packages/SystemUI/shared/src/com/android/systemui/shared/statusbar/phone/BarTransitions.java
index f62a79f..c123306 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/statusbar/phone/BarTransitions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,11 +14,13 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shared.statusbar.phone;
+import android.annotation.ColorInt;
import android.annotation.IntDef;
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -34,8 +36,6 @@
import android.view.View;
import com.android.app.animation.Interpolators;
-import com.android.settingslib.Utils;
-import com.android.systemui.res.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -44,6 +44,11 @@
private static final boolean DEBUG = false;
private static final boolean DEBUG_COLORS = false;
+ @ColorInt
+ private static final int SYSTEM_BAR_BACKGROUND_OPAQUE = Color.BLACK;
+ @ColorInt
+ private static final int SYSTEM_BAR_BACKGROUND_TRANSPARENT = Color.TRANSPARENT;
+
public static final int MODE_TRANSPARENT = 0;
public static final int MODE_SEMI_TRANSPARENT = 1;
public static final int MODE_TRANSLUCENT = 2;
@@ -183,11 +188,11 @@
mTransparent = 0x2f0000ff;
mWarning = 0xffff0000;
} else {
- mOpaque = context.getColor(R.color.system_bar_background_opaque);
+ mOpaque = SYSTEM_BAR_BACKGROUND_OPAQUE;
mSemiTransparent = context.getColor(
com.android.internal.R.color.system_bar_background_semi_transparent);
- mTransparent = context.getColor(R.color.system_bar_background_transparent);
- mWarning = Utils.getColorAttrDefaultColor(context, android.R.attr.colorError);
+ mTransparent = SYSTEM_BAR_BACKGROUND_TRANSPARENT;
+ mWarning = getColorAttrDefaultColor(context, android.R.attr.colorError, 0);
}
mGradient = context.getDrawable(gradientResourceId);
}
@@ -226,7 +231,7 @@
@Override
public void setTint(int color) {
PorterDuff.Mode targetMode = mTintFilter == null ? Mode.SRC_IN :
- mTintFilter.getMode();
+ mTintFilter.getMode();
if (mTintFilter == null || mTintFilter.getColor() != color) {
mTintFilter = new PorterDuffColorFilter(color, targetMode);
}
@@ -304,10 +309,13 @@
Interpolators.LINEAR.getInterpolation(t), 1));
mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v));
mColor = Color.argb(
- (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)),
- (int)(v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)),
- (int)(v * Color.green(targetColor) + Color.green(mColorStart) * (1 - v)),
- (int)(v * Color.blue(targetColor) + Color.blue(mColorStart) * (1 - v)));
+ (int) (v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1
+ - v)),
+ (int) (v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)),
+ (int) (v * Color.green(targetColor) + Color.green(mColorStart) * (1
+ - v)),
+ (int) (v * Color.blue(targetColor) + Color.blue(mColorStart) * (1
+ - v)));
}
}
if (mGradientAlpha > 0) {
@@ -332,4 +340,13 @@
}
}
}
+
+ /** Get color styled attribute {@code attr}, default to {@code defValue} if not found. */
+ @ColorInt
+ public static int getColorAttrDefaultColor(Context context, int attr, @ColorInt int defValue) {
+ TypedArray ta = context.obtainStyledAttributes(new int[] {attr});
+ @ColorInt int colorAccent = ta.getColor(0, defValue);
+ ta.recycle();
+ return colorAccent;
+ }
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index c0c8b75..a614fc1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -124,6 +124,8 @@
public static final long SYSUI_STATE_SHORTCUT_HELPER_SHOWING = 1L << 32;
// Touchpad gestures are disabled
public static final long SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED = 1L << 33;
+ // PiP animation is running
+ public static final long SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING = 1L << 34;
// Mask for SystemUiStateFlags to isolate SYSUI_STATE_AWAKE and
// SYSUI_STATE_WAKEFULNESS_TRANSITION, to match WAKEFULNESS_* constants
@@ -173,6 +175,7 @@
SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY,
SYSUI_STATE_SHORTCUT_HELPER_SHOWING,
SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED,
+ SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING,
})
public @interface SystemUiStateFlags {}
@@ -277,6 +280,9 @@
if ((flags & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) != 0) {
str.add("touchpad_gestures_disabled");
}
+ if ((flags & SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING) != 0) {
+ str.add("disable_gesture_pip_animating");
+ }
return str.toString();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
index 5e76801..bf1f93f 100644
--- a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
@@ -28,6 +28,7 @@
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
@@ -86,6 +87,12 @@
* Trigger ActiveUnlock when the assistant is triggered.
*/
ASSISTANT,
+ /**
+ * Trigger ActiveUnlock on legacy unlock intents. This includes tapping on the empty space
+ * of the notification shadse when face auth is enrolled and re-trying face auth on the
+ * primary bouncer.
+ */
+ UNLOCK_INTENT_LEGACY,
}
/**
@@ -99,6 +106,7 @@
}
private var requestActiveUnlockOnWakeup = false
+ private var requestActiveUnlockOnUnlockIntentLegacy = false
private var requestActiveUnlockOnUnlockIntent = false
private var requestActiveUnlockOnBioFail = false
@@ -110,6 +118,8 @@
private val settingsObserver = object : ContentObserver(handler) {
private val wakeUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)
+ private val unlockIntentLegacyUri =
+ secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY)
private val unlockIntentUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT)
private val bioFailUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)
private val faceErrorsUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ERRORS)
@@ -164,6 +174,15 @@
ACTIVE_UNLOCK_ON_WAKE, 0, selectedUserInteractor.getSelectedUserId()) == 1
}
+ if (selfChange || uris.contains(unlockIntentLegacyUri)) {
+ requestActiveUnlockOnUnlockIntentLegacy =
+ secureSettings.getIntForUser(
+ ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY,
+ 0,
+ selectedUserInteractor.getSelectedUserId()
+ ) == 1
+ }
+
if (selfChange || uris.contains(unlockIntentUri)) {
requestActiveUnlockOnUnlockIntent = secureSettings.getIntForUser(
ACTIVE_UNLOCK_ON_UNLOCK_INTENT, 0,
@@ -257,7 +276,7 @@
*/
fun isActiveUnlockEnabled(): Boolean {
return requestActiveUnlockOnWakeup || requestActiveUnlockOnUnlockIntent ||
- requestActiveUnlockOnBioFail
+ requestActiveUnlockOnBioFail || requestActiveUnlockOnUnlockIntentLegacy
}
/**
@@ -299,15 +318,18 @@
fun shouldAllowActiveUnlockFromOrigin(requestOrigin: ActiveUnlockRequestOrigin): Boolean {
return when (requestOrigin) {
ActiveUnlockRequestOrigin.WAKE -> requestActiveUnlockOnWakeup
-
+ ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY ->
+ requestActiveUnlockOnUnlockIntentLegacy
ActiveUnlockRequestOrigin.UNLOCK_INTENT ->
- requestActiveUnlockOnUnlockIntent || requestActiveUnlockOnWakeup ||
- (shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment())
-
+ requestActiveUnlockOnUnlockIntent ||
+ requestActiveUnlockOnUnlockIntentLegacy ||
+ requestActiveUnlockOnWakeup ||
+ (shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment())
ActiveUnlockRequestOrigin.BIOMETRIC_FAIL ->
- requestActiveUnlockOnBioFail || requestActiveUnlockOnUnlockIntent ||
- requestActiveUnlockOnWakeup
-
+ requestActiveUnlockOnBioFail ||
+ requestActiveUnlockOnUnlockIntentLegacy ||
+ requestActiveUnlockOnUnlockIntent ||
+ requestActiveUnlockOnWakeup
ActiveUnlockRequestOrigin.ASSISTANT -> isActiveUnlockEnabled()
}
}
@@ -345,6 +367,9 @@
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println("Settings:")
pw.println(" requestActiveUnlockOnWakeup=$requestActiveUnlockOnWakeup")
+ pw.println(
+ " requestActiveUnlockOnUnlockIntentLegacy=$requestActiveUnlockOnUnlockIntentLegacy"
+ )
pw.println(" requestActiveUnlockOnUnlockIntent=$requestActiveUnlockOnUnlockIntent")
pw.println(" requestActiveUnlockOnBioFail=$requestActiveUnlockOnBioFail")
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 4af366c..0f11717 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -39,7 +39,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.statusbar.policy.KeyguardStateController;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 42838ae..428cd0e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -351,7 +351,7 @@
mDeviceEntryFaceAuthInteractor.onSwipeUpOnBouncer();
if (mDeviceEntryFaceAuthInteractor.isFaceAuthEnabledAndEnrolled()) {
mUpdateMonitor.requestActiveUnlock(
- ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY,
"swipeUpOnBouncer");
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 4b07402..56de5a3 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -38,7 +38,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index 9d573d3..4a28d8b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -469,6 +469,7 @@
private void onSpringAnimationsEndAction() {
if (mShouldShowDockTooltip) {
+ mEduTooltipView.ifPresent(this::removeTooltip);
mEduTooltipView = Optional.of(new MenuEduTooltipView(mContext, mMenuViewAppearance));
mEduTooltipView.ifPresent(view -> addTooltipView(view,
getContext().getText(R.string.accessibility_floating_button_docking_tooltip),
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java
index f905241..636bc5b 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java
@@ -38,6 +38,7 @@
import com.android.systemui.ambient.touch.scrim.ScrimController;
import com.android.systemui.ambient.touch.scrim.ScrimManager;
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
+import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -103,6 +104,8 @@
private final UiEventLogger mUiEventLogger;
+ private final ActivityStarter mActivityStarter;
+
private final ScrimManager.Callback mScrimManagerCallback = new ScrimManager.Callback() {
@Override
public void onScrimControllerChanged(ScrimController controller) {
@@ -149,11 +152,16 @@
return true;
}
- // If scrolling up and keyguard is not locked, dismiss the dream since there's
- // no bouncer to show.
+ // If scrolling up and keyguard is not locked, dismiss both keyguard and the
+ // dream since there's no bouncer to show.
if (e1.getY() > e2.getY()
&& !mLockPatternUtils.isSecure(mUserTracker.getUserId())) {
- mCentralSurfaces.get().awakenDreams();
+ mActivityStarter.executeRunnableDismissingKeyguard(
+ () -> mCentralSurfaces.get().awakenDreams(),
+ /* cancelAction= */ null,
+ /* dismissShade= */ true,
+ /* afterKeyguardGone= */ true,
+ /* deferred= */ false);
return true;
}
@@ -162,7 +170,6 @@
// bouncer. As that view's expansion shrinks, the bouncer appears. The bouncer
// is fully hidden at full expansion (1) and fully visible when fully collapsed
// (0).
- final float dragDownAmount = e2.getY() - e1.getY();
final float screenTravelPercentage = Math.abs(e1.getY() - e2.getY())
/ mTouchSession.getBounds().height();
setPanelExpansion(1 - screenTravelPercentage);
@@ -216,7 +223,8 @@
FlingAnimationUtils flingAnimationUtilsClosing,
@Named(BouncerSwipeModule.SWIPE_TO_BOUNCER_START_REGION) float swipeRegionPercentage,
@Named(BouncerSwipeModule.MIN_BOUNCER_ZONE_SCREEN_PERCENTAGE) float minRegionPercentage,
- UiEventLogger uiEventLogger) {
+ UiEventLogger uiEventLogger,
+ ActivityStarter activityStarter) {
mCentralSurfaces = centralSurfaces;
mScrimManager = scrimManager;
mNotificationShadeWindowController = notificationShadeWindowController;
@@ -229,6 +237,7 @@
mValueAnimatorCreator = valueAnimatorCreator;
mVelocityTrackerFactory = velocityTrackerFactory;
mUiEventLogger = uiEventLogger;
+ mActivityStarter = activityStarter;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index 0cdb376..7dfa4f9 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -31,9 +31,9 @@
import android.view.View;
import com.android.settingslib.Utils;
-import com.android.systemui.navigationbar.NavigationBar;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarTransitions;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarTransitions;
import com.android.systemui.res.R;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index ad142a8..9d3c6a4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -558,7 +558,12 @@
Log.w(TAG, "onTouch down received without a preceding up");
}
mActivePointerId = MotionEvent.INVALID_POINTER_ID;
- mOnFingerDown = false;
+
+ // It's possible on some devices to get duplicate touches from both doze and the
+ // normal touch listener. Don't reset the down in this case to avoid duplicate downs
+ if (!mIsAodInterruptActive) {
+ mOnFingerDown = false;
+ }
} else if (!DeviceEntryUdfpsRefactor.isEnabled()) {
if ((mLockscreenShadeTransitionController.getQSDragProgress() != 0f
&& !mAlternateBouncerInteractor.isVisibleState())
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 01cc33c..e03d160 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -45,7 +45,6 @@
import androidx.annotation.LayoutRes
import androidx.annotation.VisibleForTesting
import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.Flags.udfpsViewPerformance
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
@@ -82,67 +81,66 @@
private const val TAG = "UdfpsControllerOverlay"
-@VisibleForTesting
-const val SETTING_REMOVE_ENROLLMENT_UI = "udfps_overlay_remove_enrollment_ui"
+@VisibleForTesting const val SETTING_REMOVE_ENROLLMENT_UI = "udfps_overlay_remove_enrollment_ui"
/**
* Keeps track of the overlay state and UI resources associated with a single FingerprintService
- * request. This state can persist across configuration changes via the [show] and [hide]
- * methods.
+ * request. This state can persist across configuration changes via the [show] and [hide] methods.
*/
@ExperimentalCoroutinesApi
@UiThread
-class UdfpsControllerOverlay @JvmOverloads constructor(
- private val context: Context,
- private val inflater: LayoutInflater,
- private val windowManager: WindowManager,
- private val accessibilityManager: AccessibilityManager,
- private val statusBarStateController: StatusBarStateController,
- private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
- private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
- private val dialogManager: SystemUIDialogManager,
- private val dumpManager: DumpManager,
- private val transitionController: LockscreenShadeTransitionController,
- private val configurationController: ConfigurationController,
- private val keyguardStateController: KeyguardStateController,
- private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
- private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
- val requestId: Long,
- @RequestReason val requestReason: Int,
- private val controllerCallback: IUdfpsOverlayControllerCallback,
- private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
- private val activityTransitionAnimator: ActivityTransitionAnimator,
- private val primaryBouncerInteractor: PrimaryBouncerInteractor,
- private val alternateBouncerInteractor: AlternateBouncerInteractor,
- private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
- private val udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate,
- private val transitionInteractor: KeyguardTransitionInteractor,
- private val selectedUserInteractor: SelectedUserInteractor,
- private val deviceEntryUdfpsTouchOverlayViewModel:
- Lazy<DeviceEntryUdfpsTouchOverlayViewModel>,
- private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>,
- private val shadeInteractor: ShadeInteractor,
- private val udfpsOverlayInteractor: UdfpsOverlayInteractor,
- private val powerInteractor: PowerInteractor,
- @Application private val scope: CoroutineScope,
+class UdfpsControllerOverlay
+@JvmOverloads
+constructor(
+ private val context: Context,
+ private val inflater: LayoutInflater,
+ private val windowManager: WindowManager,
+ private val accessibilityManager: AccessibilityManager,
+ private val statusBarStateController: StatusBarStateController,
+ private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
+ private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+ private val dialogManager: SystemUIDialogManager,
+ private val dumpManager: DumpManager,
+ private val transitionController: LockscreenShadeTransitionController,
+ private val configurationController: ConfigurationController,
+ private val keyguardStateController: KeyguardStateController,
+ private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
+ private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
+ val requestId: Long,
+ @RequestReason val requestReason: Int,
+ private val controllerCallback: IUdfpsOverlayControllerCallback,
+ private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
+ private val activityTransitionAnimator: ActivityTransitionAnimator,
+ private val primaryBouncerInteractor: PrimaryBouncerInteractor,
+ private val alternateBouncerInteractor: AlternateBouncerInteractor,
+ private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
+ private val udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate,
+ private val transitionInteractor: KeyguardTransitionInteractor,
+ private val selectedUserInteractor: SelectedUserInteractor,
+ private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>,
+ private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>,
+ private val shadeInteractor: ShadeInteractor,
+ private val udfpsOverlayInteractor: UdfpsOverlayInteractor,
+ private val powerInteractor: PowerInteractor,
+ @Application private val scope: CoroutineScope,
) {
private val currentStateUpdatedToOffAodOrDozing: Flow<Unit> =
transitionInteractor.currentKeyguardState
.filter {
- it == KeyguardState.OFF ||
- it == KeyguardState.AOD ||
- it == KeyguardState.DOZING
+ it == KeyguardState.OFF || it == KeyguardState.AOD || it == KeyguardState.DOZING
}
- .map { } // map to Unit
+ .map {} // map to Unit
private var listenForCurrentKeyguardState: Job? = null
private var addViewRunnable: Runnable? = null
private var overlayViewLegacy: UdfpsView? = null
private set
+
private var overlayTouchView: UdfpsTouchOverlay? = null
/**
- * Get the current UDFPS overlay touch view which is a different View depending on whether
- * the DeviceEntryUdfpsRefactor flag is enabled or not.
+ * Get the current UDFPS overlay touch view which is a different View depending on whether the
+ * DeviceEntryUdfpsRefactor flag is enabled or not.
+ *
* @return The view, when [isShowing], else null
*/
fun getTouchOverlay(): View? {
@@ -158,23 +156,28 @@
private var overlayTouchListener: TouchExplorationStateChangeListener? = null
- private val coreLayoutParams = WindowManager.LayoutParams(
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
- 0 /* flags set in computeLayoutParams() */,
- PixelFormat.TRANSLUCENT
- ).apply {
- title = TAG
- fitInsetsTypes = 0
- gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
- layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- flags = (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or
- WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
- privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY or
- WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION
- // Avoid announcing window title.
- accessibilityTitle = " "
- inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
- }
+ private val coreLayoutParams =
+ WindowManager.LayoutParams(
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ 0 /* flags set in computeLayoutParams() */,
+ PixelFormat.TRANSLUCENT
+ )
+ .apply {
+ title = TAG
+ fitInsetsTypes = 0
+ gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
+ layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ flags =
+ (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or
+ WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
+ privateFlags =
+ WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY or
+ WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION
+ // Avoid announcing window title.
+ accessibilityTitle = " "
+ inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
+ }
/** If the overlay is currently showing. */
val isShowing: Boolean
@@ -209,51 +212,51 @@
sensorBounds = Rect(params.sensorBounds)
try {
if (DeviceEntryUdfpsRefactor.isEnabled) {
- overlayTouchView = (inflater.inflate(
- R.layout.udfps_touch_overlay, null, false
- ) as UdfpsTouchOverlay).apply {
- // This view overlaps the sensor area
- // prevent it from being selectable during a11y
- if (requestReason.isImportantForAccessibility()) {
- importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
- }
+ overlayTouchView =
+ (inflater.inflate(R.layout.udfps_touch_overlay, null, false)
+ as UdfpsTouchOverlay)
+ .apply {
+ // This view overlaps the sensor area
+ // prevent it from being selectable during a11y
+ if (requestReason.isImportantForAccessibility()) {
+ importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
+ }
- addViewNowOrLater(this, null)
- when (requestReason) {
- REASON_AUTH_KEYGUARD ->
- UdfpsTouchOverlayBinder.bind(
- view = this,
- viewModel = deviceEntryUdfpsTouchOverlayViewModel.get(),
- udfpsOverlayInteractor = udfpsOverlayInteractor,
- )
- else ->
- UdfpsTouchOverlayBinder.bind(
- view = this,
- viewModel = defaultUdfpsTouchOverlayViewModel.get(),
- udfpsOverlayInteractor = udfpsOverlayInteractor,
- )
- }
- }
+ addViewNowOrLater(this, null)
+ when (requestReason) {
+ REASON_AUTH_KEYGUARD ->
+ UdfpsTouchOverlayBinder.bind(
+ view = this,
+ viewModel = deviceEntryUdfpsTouchOverlayViewModel.get(),
+ udfpsOverlayInteractor = udfpsOverlayInteractor,
+ )
+ else ->
+ UdfpsTouchOverlayBinder.bind(
+ view = this,
+ viewModel = defaultUdfpsTouchOverlayViewModel.get(),
+ udfpsOverlayInteractor = udfpsOverlayInteractor,
+ )
+ }
+ }
} else {
- overlayViewLegacy = (inflater.inflate(
- R.layout.udfps_view, null, false
- ) as UdfpsView).apply {
- overlayParams = params
- setUdfpsDisplayModeProvider(udfpsDisplayModeProvider)
- val animation = inflateUdfpsAnimation(this, controller)
- if (animation != null) {
- animation.init()
- animationViewController = animation
- }
- // This view overlaps the sensor area
- // prevent it from being selectable during a11y
- if (requestReason.isImportantForAccessibility()) {
- importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
- }
+ overlayViewLegacy =
+ (inflater.inflate(R.layout.udfps_view, null, false) as UdfpsView).apply {
+ overlayParams = params
+ setUdfpsDisplayModeProvider(udfpsDisplayModeProvider)
+ val animation = inflateUdfpsAnimation(this, controller)
+ if (animation != null) {
+ animation.init()
+ animationViewController = animation
+ }
+ // This view overlaps the sensor area
+ // prevent it from being selectable during a11y
+ if (requestReason.isImportantForAccessibility()) {
+ importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
+ }
- addViewNowOrLater(this, animation)
- sensorRect = sensorBounds
- }
+ addViewNowOrLater(this, animation)
+ sensorRect = sensorBounds
+ }
}
getTouchOverlay()?.apply {
touchExplorationEnabled = accessibilityManager.isTouchExplorationEnabled
@@ -269,7 +272,7 @@
}
}
accessibilityManager.addTouchExplorationStateChangeListener(
- overlayTouchListener!!
+ overlayTouchListener!!
)
overlayTouchListener?.onTouchExplorationStateChanged(true)
}
@@ -284,30 +287,18 @@
}
private fun addViewNowOrLater(view: View, animation: UdfpsAnimationViewController<*>?) {
- if (udfpsViewPerformance()) {
- addViewRunnable = kotlinx.coroutines.Runnable {
+ addViewRunnable =
+ kotlinx.coroutines.Runnable {
Trace.setCounter("UdfpsAddView", 1)
- windowManager.addView(
- view,
- coreLayoutParams.updateDimensions(animation)
- )
+ windowManager.addView(view, coreLayoutParams.updateDimensions(animation))
}
- if (powerInteractor.detailedWakefulness.value.isAwake()) {
- // Device is awake, so we add the view immediately.
- addViewIfPending()
- } else {
- listenForCurrentKeyguardState?.cancel()
- listenForCurrentKeyguardState = scope.launch {
- currentStateUpdatedToOffAodOrDozing.collect {
- addViewIfPending()
- }
- }
- }
+ if (powerInteractor.detailedWakefulness.value.isAwake()) {
+ // Device is awake, so we add the view immediately.
+ addViewIfPending()
} else {
- windowManager.addView(
- view,
- coreLayoutParams.updateDimensions(animation)
- )
+ listenForCurrentKeyguardState?.cancel()
+ listenForCurrentKeyguardState =
+ scope.launch { currentStateUpdatedToOffAodOrDozing.collect { addViewIfPending() } }
}
}
@@ -340,23 +331,26 @@
): UdfpsAnimationViewController<*>? {
DeviceEntryUdfpsRefactor.assertInLegacyMode()
- val isEnrollment = when (requestReason) {
- REASON_ENROLL_FIND_SENSOR, REASON_ENROLL_ENROLLING -> true
- else -> false
- }
+ val isEnrollment =
+ when (requestReason) {
+ REASON_ENROLL_FIND_SENSOR,
+ REASON_ENROLL_ENROLLING -> true
+ else -> false
+ }
- val filteredRequestReason = if (isEnrollment && shouldRemoveEnrollmentUi()) {
- REASON_AUTH_OTHER
- } else {
- requestReason
- }
+ val filteredRequestReason =
+ if (isEnrollment && shouldRemoveEnrollmentUi()) {
+ REASON_AUTH_OTHER
+ } else {
+ requestReason
+ }
return when (filteredRequestReason) {
REASON_ENROLL_FIND_SENSOR,
REASON_ENROLL_ENROLLING -> {
// Enroll udfps UI is handled by settings, so use empty view here
UdfpsFpmEmptyViewController(
- view.addUdfpsView(R.layout.udfps_fpm_empty_view){
+ view.addUdfpsView(R.layout.udfps_fpm_empty_view) {
updateAccessibilityViewLocation(sensorBounds)
},
statusBarStateController,
@@ -434,14 +428,10 @@
udfpsDisplayModeProvider.disable(null)
}
getTouchOverlay()?.apply {
- if (udfpsViewPerformance()) {
- if (this.parent != null) {
- windowManager.removeView(this)
- }
- Trace.setCounter("UdfpsAddView", 0)
- } else {
+ if (this.parent != null) {
windowManager.removeView(this)
}
+ Trace.setCounter("UdfpsAddView", 0)
setOnTouchListener(null)
setOnHoverListener(null)
overlayTouchListener?.let {
@@ -475,22 +465,19 @@
val paddingX = animation?.paddingX ?: 0
val paddingY = animation?.paddingY ?: 0
- val isEnrollment = when (requestReason) {
- REASON_ENROLL_FIND_SENSOR, REASON_ENROLL_ENROLLING -> true
- else -> false
- }
+ val isEnrollment =
+ when (requestReason) {
+ REASON_ENROLL_FIND_SENSOR,
+ REASON_ENROLL_ENROLLING -> true
+ else -> false
+ }
// Use expanded overlay unless touchExploration enabled
var rotatedBounds =
if (accessibilityManager.isTouchExplorationEnabled && isEnrollment) {
Rect(overlayParams.sensorBounds)
} else {
- Rect(
- 0,
- 0,
- overlayParams.naturalDisplayWidth,
- overlayParams.naturalDisplayHeight
- )
+ Rect(0, 0, overlayParams.naturalDisplayWidth, overlayParams.naturalDisplayHeight)
}
val rot = overlayParams.rotation
@@ -498,7 +485,8 @@
if (!shouldRotate(animation)) {
Log.v(
TAG,
- "Skip rotating UDFPS bounds " + Surface.rotationToString(rot) +
+ "Skip rotating UDFPS bounds " +
+ Surface.rotationToString(rot) +
" animation=$animation" +
" isGoingToSleep=${keyguardUpdateMonitor.isGoingToSleep}" +
" isOccluded=${keyguardStateController.isOccluded}"
@@ -559,6 +547,4 @@
@RequestReason
private fun Int.isImportantForAccessibility() =
- this == REASON_ENROLL_FIND_SENSOR ||
- this == REASON_ENROLL_ENROLLING ||
- this == REASON_AUTH_BP
+ this == REASON_ENROLL_FIND_SENSOR || this == REASON_ENROLL_ENROLLING || this == REASON_AUTH_BP
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
index a742c0e..8c64b76 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.biometrics.domain.interactor
import android.hardware.biometrics.AuthenticateOptions
@@ -21,16 +23,22 @@
import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.display.data.repository.DeviceStateRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
@@ -76,22 +84,36 @@
deviceStateRepository: DeviceStateRepository,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
udfpsOverlayInteractor: UdfpsOverlayInteractor,
+ deviceEntryInteractor: Lazy<DeviceEntryInteractor>,
) : LogContextInteractor {
- override val displayState =
- keyguardTransitionInteractor.startedKeyguardTransitionStep.map {
- when (it.to) {
- KeyguardState.LOCKSCREEN,
- KeyguardState.OCCLUDED,
- KeyguardState.ALTERNATE_BOUNCER,
- KeyguardState.PRIMARY_BOUNCER -> AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
- KeyguardState.AOD -> AuthenticateOptions.DISPLAY_STATE_AOD
- KeyguardState.OFF,
- KeyguardState.DOZING -> AuthenticateOptions.DISPLAY_STATE_NO_UI
- KeyguardState.DREAMING -> AuthenticateOptions.DISPLAY_STATE_SCREENSAVER
- else -> AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ override val displayState: Flow<Int> by lazy {
+ if (SceneContainerFlag.isEnabled) {
+ combine(
+ deviceEntryInteractor.get().isDeviceEntered,
+ keyguardTransitionInteractor.startedKeyguardTransitionStep,
+ ) { isDeviceEntered, transitionStep ->
+ if (isDeviceEntered) {
+ AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ } else {
+ transitionStep.toAuthenticateOptions(
+ // Here when isDeviceEntered=false which always means that the device is on
+ // top of the keyguard. Therefore, any KeyguardState that doesn't have a
+ // more specific mapping as a sub-state of keyguard, maps to LOCKSCREEN
+ // instead of UNKNOWN, because it _is_ a known display state and that
+ // display state is undeniably LOCKSCREEN.
+ default = AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
+ )
+ }
+ }
+ } else {
+ keyguardTransitionInteractor.startedKeyguardTransitionStep.map { transitionStep ->
+ transitionStep.toAuthenticateOptions(
+ default = AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ )
}
}
+ }
override val isHardwareIgnoringTouches: Flow<Boolean> =
udfpsOverlayInteractor.shouldHandleTouches.map { shouldHandle -> !shouldHandle }
@@ -152,6 +174,21 @@
}
}
+ private fun TransitionStep.toAuthenticateOptions(default: Int): Int {
+ return when (this.to) {
+ KeyguardState.LOCKSCREEN,
+ KeyguardState.OCCLUDED,
+ KeyguardState.ALTERNATE_BOUNCER,
+ KeyguardState.PRIMARY_BOUNCER -> AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
+ KeyguardState.AOD -> AuthenticateOptions.DISPLAY_STATE_AOD
+ KeyguardState.OFF,
+ KeyguardState.DOZING -> AuthenticateOptions.DISPLAY_STATE_NO_UI
+ KeyguardState.DREAMING -> AuthenticateOptions.DISPLAY_STATE_SCREENSAVER
+ KeyguardState.GONE -> AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+ else -> default
+ }
+ }
+
companion object {
private const val TAG = "ContextRepositoryImpl"
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 408e2c2..c868d01 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -580,18 +580,23 @@
}
}
- private suspend fun getHelpForSuccessfulAuthentication(
+ private fun getHelpForSuccessfulAuthentication(
authenticatedModality: BiometricModality,
- ): Int? =
- when {
- // for coex, show a message when face succeeds after fingerprint has also started
- modalities.hasFaceAndFingerprint &&
- (viewModel.fingerprintStartMode.first() != FingerprintStartMode.Pending) &&
- (authenticatedModality == BiometricModality.Face) ->
- R.string.biometric_dialog_tap_confirm_with_face_alt_1
- else -> null
+ ): Int? {
+ // for coex, show a message when face succeeds after fingerprint has also started
+ if (authenticatedModality != BiometricModality.Face) {
+ return null
}
+ if (modalities.hasUdfps) {
+ return R.string.biometric_dialog_tap_confirm_with_face_alt_1
+ }
+ if (modalities.hasSfps) {
+ return R.string.biometric_dialog_tap_confirm_with_face_sfps
+ }
+ return null
+ }
+
fun onAuthenticationFailed(
@BiometricAuthenticator.Modality modality: Int,
failureReason: String,
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
index 94f465d..eaddc42 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
@@ -288,11 +288,13 @@
private fun startSettingsActivity(intent: Intent, view: View) {
if (job?.isActive == true) {
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
- activityStarter.postStartActivityDismissingKeyguard(
- intent,
- 0,
- dialogTransitionAnimator.createActivityTransitionController(view)
- )
+ val controller = dialogTransitionAnimator.createActivityTransitionController(view)
+ // The controller will be null when the screen is locked and going to show the
+ // primary bouncer. In this case we dismiss the dialog manually.
+ if (controller == null) {
+ cancelJob()
+ }
+ activityStarter.postStartActivityDismissingKeyguard(intent, 0, controller)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index e31f1ad..88c3f9f6 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -18,7 +18,6 @@
import android.provider.Settings
import com.android.compose.animation.scene.SceneKey
-import com.android.compose.animation.scene.TransitionKey
import com.android.systemui.CoreStartable
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -92,8 +91,8 @@
keyguardTransitionInteractor.startedKeyguardTransitionStep
.mapLatest(::determineSceneAfterTransition)
.filterNotNull()
- .onEach { (nextScene, nextTransition) ->
- communalSceneInteractor.changeScene(nextScene, nextTransition)
+ .onEach { nextScene ->
+ communalSceneInteractor.changeScene(nextScene, CommunalTransitionKeys.SimpleFade)
}
.launchIn(applicationScope)
@@ -189,7 +188,7 @@
private suspend fun determineSceneAfterTransition(
lastStartedTransition: TransitionStep,
- ): Pair<SceneKey, TransitionKey>? {
+ ): SceneKey? {
val to = lastStartedTransition.to
val from = lastStartedTransition.from
val docked = dockManager.isDocked
@@ -202,27 +201,22 @@
// underneath the hub is shown. When launching activities over lockscreen, we only
// change scenes once the activity launch animation is finished, so avoid
// changing the scene here.
- Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
+ CommunalScenes.Blank
}
to == KeyguardState.GLANCEABLE_HUB && from == KeyguardState.OCCLUDED -> {
// When transitioning to the hub from an occluded state, fade out the hub without
// doing any translation.
- Pair(CommunalScenes.Communal, CommunalTransitionKeys.SimpleFade)
+ CommunalScenes.Communal
}
// Transitioning to Blank scene when entering the edit mode will be handled separately
// with custom animations.
to == KeyguardState.GONE && !communalInteractor.editModeOpen.value ->
- Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
+ CommunalScenes.Blank
!docked && !KeyguardState.deviceIsAwakeInState(to) -> {
// If the user taps the screen and wakes the device within this timeout, we don't
// want to dismiss the hub
delay(AWAKE_DEBOUNCE_DELAY)
- Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
- }
- from == KeyguardState.DOZING && to == KeyguardState.GLANCEABLE_HUB -> {
- // Make sure the communal hub is showing (immediately, not fading in) when
- // transitioning from dozing to hub.
- Pair(CommunalScenes.Communal, CommunalTransitionKeys.Immediately)
+ CommunalScenes.Blank
}
else -> null
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt
index 5cd15f2..75f0bad 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt
@@ -17,7 +17,6 @@
package com.android.systemui.communal.data.model
import android.appwidget.AppWidgetProviderInfo
-import com.android.settingslib.flags.Flags.allowAllWidgetsOnLockscreenByDefault
/**
* The widget categories to display on communal hub (where categories is a bitfield with values that
@@ -31,9 +30,7 @@
val defaultCategories: Int
get() {
return AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD or
- if (allowAllWidgetsOnLockscreenByDefault())
- AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN
- else 0
+ AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
index 1c47e50..e3ef6bb 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
@@ -24,7 +24,6 @@
import com.android.systemui.Flags.communalHub
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.communal.data.model.CommunalEnabledState
-import com.android.systemui.communal.data.model.CommunalWidgetCategories
import com.android.systemui.communal.data.model.DisabledReason
import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_DEVICE_POLICY
import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_FLAG
@@ -52,12 +51,6 @@
/** A [CommunalEnabledState] for the specified user. */
fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState>
- /**
- * A flow that reports the widget categories to show on the hub as selected by the user in
- * Settings.
- */
- fun getWidgetCategories(user: UserInfo): Flow<CommunalWidgetCategories>
-
/** Keyguard widgets enabled state by Device Policy Manager for the specified user. */
fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean>
@@ -104,22 +97,6 @@
.flowOn(bgDispatcher)
}
- override fun getWidgetCategories(user: UserInfo): Flow<CommunalWidgetCategories> =
- secureSettings
- .observerFlow(userId = user.id, names = arrayOf(GLANCEABLE_HUB_CONTENT_SETTING))
- // Force an update
- .onStart { emit(Unit) }
- .map {
- CommunalWidgetCategories(
- secureSettings.getIntForUser(
- GLANCEABLE_HUB_CONTENT_SETTING,
- CommunalWidgetCategories.defaultCategories,
- user.id
- )
- )
- }
- .flowOn(bgDispatcher)
-
override fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> =
broadcastDispatcher
.broadcastFlow(
@@ -138,11 +115,11 @@
val intType =
secureSettings.getIntForUser(
GLANCEABLE_HUB_BACKGROUND_SETTING,
- CommunalBackgroundType.DEFAULT.value,
+ CommunalBackgroundType.ANIMATED.value,
user.id
)
CommunalBackgroundType.entries.find { type -> type.value == intType }
- ?: CommunalBackgroundType.DEFAULT
+ ?: CommunalBackgroundType.ANIMATED
}
private fun getEnabledByUser(user: UserInfo): Flow<Boolean> =
@@ -159,7 +136,6 @@
}
companion object {
- const val GLANCEABLE_HUB_CONTENT_SETTING = "glanceable_hub_content_setting"
const val GLANCEABLE_HUB_BACKGROUND_SETTING = "glanceable_hub_background"
private const val ENABLED_SETTING_DEFAULT = 1
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 9f3ade9..f5255ac 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -392,26 +392,17 @@
allowedForWorkProfile ->
filterWidgetsAllowedByDevicePolicy(widgets, allowedForWorkProfile)
},
- communalSettingsInteractor.communalWidgetCategories,
updateOnWorkProfileBroadcastReceived,
- ) { widgets, allowedCategories, _ ->
+ ) { widgets, _ ->
widgets.map { widget ->
when (widget) {
is CommunalWidgetContentModel.Available -> {
- if (widget.providerInfo.widgetCategory and allowedCategories != 0) {
- // At least one category this widget specified is allowed, so show it
- WidgetContent.Widget(
- appWidgetId = widget.appWidgetId,
- providerInfo = widget.providerInfo,
- appWidgetHost = appWidgetHost,
- inQuietMode = isQuietModeEnabled(widget.providerInfo.profile)
- )
- } else {
- WidgetContent.DisabledWidget(
- appWidgetId = widget.appWidgetId,
- providerInfo = widget.providerInfo,
- )
- }
+ WidgetContent.Widget(
+ appWidgetId = widget.appWidgetId,
+ providerInfo = widget.providerInfo,
+ appWidgetHost = appWidgetHost,
+ inQuietMode = isQuietModeEnabled(widget.providerInfo.profile)
+ )
}
is CommunalWidgetContentModel.Pending -> {
WidgetContent.PendingWidget(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
index f043d58..47b75c4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
@@ -19,7 +19,6 @@
import android.content.pm.UserInfo
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.communal.data.model.CommunalEnabledState
-import com.android.systemui.communal.data.model.CommunalWidgetCategories
import com.android.systemui.communal.data.repository.CommunalSettingsRepository
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.dagger.SysUISingleton
@@ -70,18 +69,6 @@
// Start this eagerly since the value is accessed synchronously in many places.
.stateIn(scope = bgScope, started = SharingStarted.Eagerly, initialValue = false)
- /** What widget categories to show on the hub. */
- val communalWidgetCategories: StateFlow<Int> =
- userInteractor.selectedUserInfo
- .flatMapLatest { user -> repository.getWidgetCategories(user) }
- .map { categories -> categories.categories }
- .stateIn(
- scope = bgScope,
- // Start this eagerly since the value can be accessed synchronously.
- started = SharingStarted.Eagerly,
- initialValue = CommunalWidgetCategories.defaultCategories
- )
-
/** The type of background to use for the hub. Used to experiment with different backgrounds */
val communalBackground: Flow<CommunalBackgroundType> =
userInteractor.selectedUserInfo
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
index 4eaba06..3b23ba9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
@@ -18,7 +18,7 @@
/** Models the types of background that can be shown on the hub. */
enum class CommunalBackgroundType(val value: Int) {
- DEFAULT(0),
+ STATIC(0),
STATIC_GRADIENT(1),
ANIMATED(2),
NONE(3),
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
index 9185384..2e92438 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -25,6 +25,7 @@
import androidx.activity.result.ActivityResultLauncher
import com.android.internal.logging.UiEventLogger
import com.android.systemui.Flags.enableWidgetPickerSizeFilter
+import com.android.systemui.communal.data.model.CommunalWidgetCategories
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalPrefsInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -92,7 +93,7 @@
*/
val canShowEditMode =
allOf(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE),
+ keyguardTransitionInteractor.isFinishedIn(KeyguardState.GONE),
communalInteractor.editModeOpen
)
.filter { it }
@@ -183,7 +184,7 @@
}
putExtra(
AppWidgetManager.EXTRA_CATEGORY_FILTER,
- communalSettingsInteractor.communalWidgetCategories.value
+ CommunalWidgetCategories.defaultCategories
)
putExtra(EXTRA_UI_SURFACE_KEY, EXTRA_UI_SURFACE_VALUE)
putParcelableArrayListExtra(EXTRA_ADDED_APP_WIDGETS_KEY, excludeList)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 2043dd1..f9f01f7 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -27,6 +27,7 @@
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -39,6 +40,7 @@
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
@@ -55,6 +57,8 @@
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -64,6 +68,7 @@
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/** The default view model used for showing the communal hub. */
@@ -74,6 +79,7 @@
constructor(
@Main val mainDispatcher: CoroutineDispatcher,
@Application private val scope: CoroutineScope,
+ @Background private val bgScope: CoroutineScope,
@Main private val resources: Resources,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
keyguardInteractor: KeyguardInteractor,
@@ -139,7 +145,10 @@
*/
override val isCommunalContentFlowFrozen: Flow<Boolean> =
allOf(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GLANCEABLE_HUB),
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Communal,
+ stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB
+ ),
keyguardInteractor.isKeyguardOccluded,
not(keyguardInteractor.isAbleToDream)
)
@@ -172,7 +181,10 @@
// opened.
override val isFocusable: Flow<Boolean> =
combine(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GLANCEABLE_HUB),
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Communal,
+ stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB
+ ),
communalInteractor.isIdleOnCommunal,
shadeInteractor.isAnyFullyExpanded,
) { transitionedToGlanceableHub, isIdleOnCommunal, isAnyFullyExpanded ->
@@ -303,8 +315,12 @@
*
* This is needed because the notification shade does not block touches in blank areas and these
* fall through to the glanceable hub, which we don't want.
+ *
+ * Using a StateFlow as the value does not necessarily change when hub becomes available.
*/
- val touchesAllowed: Flow<Boolean> = not(shadeInteractor.isAnyFullyExpanded)
+ val touchesAllowed: StateFlow<Boolean> =
+ not(shadeInteractor.isAnyFullyExpanded)
+ .stateIn(bgScope, SharingStarted.Eagerly, initialValue = false)
// TODO(b/339667383): remove this temporary swipe gesture handle
/**
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
index 1e04fe7..4217744 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
@@ -56,7 +56,7 @@
Color.valueOf(
Utils.getColorAttrDefaultColor(
context,
- com.android.internal.R.attr.materialColorOutlineVariant
+ com.android.internal.R.attr.materialColorPrimary
)
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt
index 76be005..af87f09 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt
@@ -22,6 +22,7 @@
import com.android.systemui.communal.widgets.EditWidgetsActivity.Companion.EXTRA_PRESELECTED_KEY
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.res.R
import javax.inject.Inject
interface EditWidgetsActivityStarter {
@@ -48,6 +49,7 @@
},
/* onlyProvisioned = */ true,
/* dismissShade = */ true,
+ applicationContext.resources.getString(R.string.unlock_reason_to_customize_widgets),
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
index cbc6c97..72f9180 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
@@ -34,10 +34,11 @@
private val activityStarter: ActivityStarter,
) : RemoteViews.InteractionHandler {
- private val delegate = InteractionHandlerDelegate(
- findViewToAnimate = { view -> view is CommunalAppWidgetHostView },
- intentStarter = this::startIntent,
- )
+ private val delegate =
+ InteractionHandlerDelegate(
+ findViewToAnimate = { view -> view is CommunalAppWidgetHostView },
+ intentStarter = this::startIntent,
+ )
override fun onInteraction(
view: View,
@@ -45,7 +46,6 @@
response: RemoteViews.RemoteResponse
): Boolean = delegate.onInteraction(view, pendingIntent, response)
-
private fun startIntent(
pendingIntent: PendingIntent,
fillInIntent: Intent,
@@ -59,6 +59,8 @@
controller,
fillInIntent,
extraOptions.toBundle(),
+ // TODO(b/325110448): UX to provide copy
+ /* customMessage = */ null,
)
return true
}
diff --git a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
index 92108e9..afa2375 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
@@ -18,7 +18,6 @@
import static com.android.systemui.complication.dagger.DreamHomeControlsComplicationComponent.DreamHomeControlsModule.DREAM_HOME_CONTROLS_CHIP_VIEW;
import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS;
-import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS;
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK;
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE;
@@ -90,7 +89,6 @@
private final DreamHomeControlsComplication mComplication;
private final DreamOverlayStateController mDreamOverlayStateController;
private final ControlsComponent mControlsComponent;
- private final boolean mReplacedByOpenHub;
private boolean mOverlayActive = false;
@@ -118,13 +116,11 @@
public Registrant(DreamHomeControlsComplication complication,
DreamOverlayStateController dreamOverlayStateController,
ControlsComponent controlsComponent,
- @SystemUser Monitor monitor,
- @Named(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS) boolean replacedByOpenHub) {
+ @SystemUser Monitor monitor) {
super(monitor);
mComplication = complication;
mControlsComponent = controlsComponent;
mDreamOverlayStateController = dreamOverlayStateController;
- mReplacedByOpenHub = replacedByOpenHub;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/complication/OpenHubComplication.java b/packages/SystemUI/src/com/android/systemui/complication/OpenHubComplication.java
deleted file mode 100644
index 05df2bb..0000000
--- a/packages/SystemUI/src/com/android/systemui/complication/OpenHubComplication.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.complication;
-
-import static com.android.systemui.complication.dagger.OpenHubComplicationComponent.OpenHubModule.OPEN_HUB_CHIP_VIEW;
-import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.OPEN_HUB_CHIP_LAYOUT_PARAMS;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.settingslib.Utils;
-import com.android.systemui.CoreStartable;
-import com.android.systemui.communal.domain.interactor.CommunalInteractor;
-import com.android.systemui.communal.shared.model.CommunalScenes;
-import com.android.systemui.complication.dagger.OpenHubComplicationComponent;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.SystemUser;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.shared.condition.Monitor;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.util.ViewController;
-import com.android.systemui.util.condition.ConditionalCoreStartable;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * A dream complication that shows a chip to open the glanceable hub.
- */
-// TODO(b/339667383): delete or properly implement this once a product decision is made
-public class OpenHubComplication implements Complication {
- private final Resources mResources;
- private final OpenHubComplicationComponent.Factory mComponentFactory;
-
- @Inject
- public OpenHubComplication(
- @Main Resources resources,
- OpenHubComplicationComponent.Factory componentFactory) {
- mResources = resources;
- mComponentFactory = componentFactory;
- }
-
- @Override
- public ViewHolder createView(ComplicationViewModel model) {
- return mComponentFactory.create(mResources).getViewHolder();
- }
-
- @Override
- public int getRequiredTypeAvailability() {
- // TODO(b/339667383): create a new complication type if we decide to productionize this
- return COMPLICATION_TYPE_NONE;
- }
-
- /**
- * {@link CoreStartable} for registering the complication with SystemUI on startup.
- */
- public static class Registrant extends ConditionalCoreStartable {
- private final OpenHubComplication mComplication;
- private final DreamOverlayStateController mDreamOverlayStateController;
-
- private boolean mOverlayActive = false;
-
- private final DreamOverlayStateController.Callback mOverlayStateCallback =
- new DreamOverlayStateController.Callback() {
- @Override
- public void onStateChanged() {
- if (mOverlayActive == mDreamOverlayStateController.isOverlayActive()) {
- return;
- }
-
- mOverlayActive = !mOverlayActive;
-
- if (mOverlayActive) {
- updateOpenHubComplication();
- }
- }
- };
-
- @Inject
- public Registrant(OpenHubComplication complication,
- DreamOverlayStateController dreamOverlayStateController,
- @SystemUser Monitor monitor) {
- super(monitor);
- mComplication = complication;
- mDreamOverlayStateController = dreamOverlayStateController;
- }
-
- @Override
- public void onStart() {
- mDreamOverlayStateController.addCallback(mOverlayStateCallback);
- }
-
- private void updateOpenHubComplication() {
- // TODO(b/339667383): don't show the complication if glanceable hub is disabled
-// if (Flags.glanceableHubShortcutButton()) {
-// mDreamOverlayStateController.addComplication(mComplication);
-// } else {
-// mDreamOverlayStateController.removeComplication(mComplication);
-// }
- }
- }
-
- /**
- * Contains values/logic associated with the dream complication view.
- */
- public static class OpenHubChipViewHolder implements ViewHolder {
- private final ImageView mView;
- private final ComplicationLayoutParams mLayoutParams;
- private final OpenHubChipViewController mViewController;
-
- @Inject
- OpenHubChipViewHolder(
- OpenHubChipViewController dreamOpenHubChipViewController,
- @Named(OPEN_HUB_CHIP_VIEW) ImageView view,
- @Named(OPEN_HUB_CHIP_LAYOUT_PARAMS) ComplicationLayoutParams layoutParams
- ) {
- mView = view;
- mLayoutParams = layoutParams;
- mViewController = dreamOpenHubChipViewController;
- mViewController.init();
- }
-
- @Override
- public ImageView getView() {
- return mView;
- }
-
- @Override
- public ComplicationLayoutParams getLayoutParams() {
- return mLayoutParams;
- }
- }
-
- /**
- * Controls behavior of the dream complication.
- */
- static class OpenHubChipViewController extends ViewController<ImageView> {
- private static final String TAG = "OpenHubCtrl";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private final Context mContext;
- private final ConfigurationController mConfigurationController;
-
- private final ConfigurationController.ConfigurationListener mConfigurationListener =
- new ConfigurationController.ConfigurationListener() {
- @Override
- public void onUiModeChanged() {
- reloadResources();
- }
- };
- private final CommunalInteractor mCommunalInteractor;
-
- @Inject
- OpenHubChipViewController(
- @Named(OPEN_HUB_CHIP_VIEW) ImageView view,
- Context context,
- ConfigurationController configurationController,
- CommunalInteractor communalInteractor) {
- super(view);
-
- mContext = context;
- mConfigurationController = configurationController;
- mCommunalInteractor = communalInteractor;
- }
-
- @Override
- protected void onViewAttached() {
- reloadResources();
- mView.setOnClickListener(this::onClickOpenHub);
- mConfigurationController.addCallback(mConfigurationListener);
- }
-
- @Override
- protected void onViewDetached() {
- mConfigurationController.removeCallback(mConfigurationListener);
- }
-
- private void reloadResources() {
- mView.setImageTintList(Utils.getColorAttr(mContext, android.R.attr.textColorPrimary));
- final Drawable background = mView.getBackground();
- if (background != null) {
- background.setTintList(
- Utils.getColorAttr(mContext, com.android.internal.R.attr.colorSurface));
- }
- }
-
- private void onClickOpenHub(View v) {
- if (DEBUG) Log.d(TAG, "open hub complication tapped");
-
- mCommunalInteractor.changeScene(CommunalScenes.Communal, null);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/OpenHubComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/OpenHubComplicationComponent.java
deleted file mode 100644
index 501601e..0000000
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/OpenHubComplicationComponent.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.complication.dagger;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.view.LayoutInflater;
-import android.widget.ImageView;
-
-import com.android.systemui.complication.OpenHubComplication;
-import com.android.systemui.res.R;
-import com.android.systemui.shared.shadow.DoubleShadowIconDrawable;
-import com.android.systemui.shared.shadow.DoubleShadowTextHelper;
-
-import dagger.BindsInstance;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Named;
-import javax.inject.Scope;
-
-/**
- * Responsible for generating dependencies for the {@link OpenHubComplication}.
- */
-@Subcomponent(modules = OpenHubComplicationComponent.OpenHubModule.class)
-@OpenHubComplicationComponent.OpenHubComplicationScope
-public interface OpenHubComplicationComponent {
- /**
- * Creates a view holder for the open hub complication.
- */
- OpenHubComplication.OpenHubChipViewHolder getViewHolder();
-
- /**
- * Scope of the open hub complication.
- */
- @Documented
- @Retention(RUNTIME)
- @Scope
- @interface OpenHubComplicationScope {
- }
-
- /**
- * Factory that generates a {@link OpenHubComplicationComponent}.
- */
- @Subcomponent.Factory
- interface Factory {
- /**
- * Creates an instance of {@link OpenHubComplicationComponent}.
- */
- OpenHubComplicationComponent create(@BindsInstance Resources resources);
- }
-
- /**
- * Scoped injected values for the {@link OpenHubComplicationComponent}.
- */
- @Module
- interface OpenHubModule {
- String OPEN_HUB_CHIP_VIEW = "open_hub_chip_view";
- String OPEN_HUB_BACKGROUND_DRAWABLE = "open_hub_background_drawable";
-
- /**
- * Provides the dream open hub chip view.
- */
- @Provides
- @OpenHubComplicationScope
- @Named(OPEN_HUB_CHIP_VIEW)
- static ImageView provideOpenHubChipView(
- LayoutInflater layoutInflater,
- @Named(OPEN_HUB_BACKGROUND_DRAWABLE) Drawable backgroundDrawable) {
- final ImageView chip =
- (ImageView) layoutInflater.inflate(R.layout.dream_overlay_open_hub_chip,
- null, false);
- chip.setBackground(backgroundDrawable);
-
- return chip;
- }
-
- /**
- * Provides the background drawable for the open hub chip.
- */
- @Provides
- @OpenHubComplicationScope
- @Named(OPEN_HUB_BACKGROUND_DRAWABLE)
- static Drawable providesOpenHubBackground(Context context, Resources resources) {
- return new DoubleShadowIconDrawable(createShadowInfo(
- resources,
- R.dimen.dream_overlay_bottom_affordance_key_text_shadow_radius,
- R.dimen.dream_overlay_bottom_affordance_key_text_shadow_dx,
- R.dimen.dream_overlay_bottom_affordance_key_text_shadow_dy,
- R.dimen.dream_overlay_bottom_affordance_key_shadow_alpha
- ),
- createShadowInfo(
- resources,
- R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_radius,
- R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_dx,
- R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_dy,
- R.dimen.dream_overlay_bottom_affordance_ambient_shadow_alpha
- ),
- resources.getDrawable(R.drawable.dream_overlay_bottom_affordance_bg),
- resources.getDimensionPixelOffset(
- R.dimen.dream_overlay_bottom_affordance_width),
- resources.getDimensionPixelSize(R.dimen.dream_overlay_bottom_affordance_inset)
- );
- }
-
- private static DoubleShadowTextHelper.ShadowInfo createShadowInfo(Resources resources,
- int blurId, int offsetXId, int offsetYId, int alphaId) {
-
- return new DoubleShadowTextHelper.ShadowInfo(
- resources.getDimension(blurId),
- resources.getDimension(offsetXId),
- resources.getDimension(offsetYId),
- resources.getFloat(alphaId)
- );
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
index edb5ff7..6f1b098 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
@@ -25,7 +25,6 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.res.R;
-import com.android.systemui.util.settings.SystemSettings;
import dagger.Module;
import dagger.Provides;
@@ -40,7 +39,6 @@
subcomponents = {
DreamClockTimeComplicationComponent.class,
DreamHomeControlsComplicationComponent.class,
- OpenHubComplicationComponent.class,
DreamMediaEntryComplicationComponent.class
})
public interface RegisteredComplicationsModule {
@@ -48,8 +46,6 @@
String DREAM_SMARTSPACE_LAYOUT_PARAMS = "smartspace_layout_params";
String DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS = "home_controls_chip_layout_params";
String DREAM_MEDIA_ENTRY_LAYOUT_PARAMS = "media_entry_layout_params";
- String OPEN_HUB_CHIP_LAYOUT_PARAMS = "open_hub_chip_layout_params";
- String OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS = "open_hub_chip_replace_home_controls";
int DREAM_CLOCK_TIME_COMPLICATION_WEIGHT = 1;
int DREAM_CLOCK_TIME_COMPLICATION_WEIGHT_NO_SMARTSPACE = 2;
@@ -113,26 +109,6 @@
}
/**
- * Provides layout parameters for the open hub complication.
- */
- @Provides
- @Named(OPEN_HUB_CHIP_LAYOUT_PARAMS)
- static ComplicationLayoutParams provideOpenHubLayoutParams(
- @Named(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS) boolean replaceHomeControls) {
- int position = ComplicationLayoutParams.POSITION_BOTTOM | (replaceHomeControls
- ? ComplicationLayoutParams.POSITION_START
- : ComplicationLayoutParams.POSITION_END);
- int direction = replaceHomeControls ? ComplicationLayoutParams.DIRECTION_END
- : ComplicationLayoutParams.DIRECTION_START;
- return new ComplicationLayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT,
- position,
- direction,
- DREAM_HOME_CONTROLS_CHIP_COMPLICATION_WEIGHT);
- }
-
- /**
* Provides layout parameters for the smartspace complication.
*/
@Provides
@@ -148,14 +124,4 @@
res.getDimensionPixelSize(R.dimen.dream_overlay_complication_smartspace_padding),
res.getDimensionPixelSize(R.dimen.dream_overlay_complication_smartspace_max_width));
}
-
- /**
- * If true, the home controls chip should not be shown and the open hub chip should be shown in
- * its place.
- */
- @Provides
- @Named(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS)
- static boolean providesOpenHubChipReplaceHomeControls(SystemSettings systemSettings) {
- return systemSettings.getBool(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS, false);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
index 813fccf..17202639 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -58,6 +58,7 @@
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.UserRepository
@@ -221,8 +222,7 @@
trySendWithFailureLogging(it.bypassEnabled, TAG, "BypassStateChanged")
awaitClose { it.unregisterOnBypassStateChangedListener(callback) }
}
- }
- ?: flowOf(false)
+ } ?: flowOf(false)
override fun setLockedOut(isLockedOut: Boolean) {
_isLockedOut.value = isLockedOut
@@ -322,7 +322,10 @@
merge(
powerInteractor.isAsleep,
combine(
- keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE),
+ keyguardTransitionInteractor.isFinishedIn(
+ scene = Scenes.Gone,
+ stateWithoutSceneContainer = KeyguardState.GONE
+ ),
keyguardInteractor.statusBarState,
) { isFinishedInGoneState, statusBarState ->
// When the user is dragging the primary bouncer in (up) by manually scrolling
@@ -733,6 +736,7 @@
pw.println(" lockscreenBypassEnabled: ${keyguardBypassController?.bypassEnabled ?: false}")
}
}
+
/** Combine two boolean flows by and-ing both of them */
private fun and(flow: Flow<Boolean>, anotherFlow: Flow<Boolean>) =
flow.combine(anotherFlow) { a, b -> a && b }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
index f779ac8..0f18978 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
@@ -39,6 +39,12 @@
* the lockscreen.
*/
val isBypassEnabled: StateFlow<Boolean>
+
+ /**
+ * Reports, to system server, that the user is "present" now. This is a signal that system
+ * server uses to know that the device has been entered.
+ */
+ suspend fun reportUserPresent()
}
/** Encapsulates application state for device entry. */
@@ -79,6 +85,13 @@
initialValue = keyguardBypassController.bypassEnabled,
)
+ override suspend fun reportUserPresent() {
+ withContext(backgroundDispatcher) {
+ val selectedUserId = userRepository.selectedUser.value.userInfo.id
+ lockPatternUtils.userPresent(selectedUserId)
+ }
+ }
+
companion object {
private const val TAG = "DeviceEntryRepositoryImpl"
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 4c7142b..425bb96 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -42,6 +42,7 @@
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -108,6 +109,11 @@
false
}
}
+ .onEach { isDeviceEntered ->
+ if (isDeviceEntered) {
+ repository.reportUserPresent()
+ }
+ }
.stateIn(
scope = applicationScope,
started = SharingStarted.Eagerly,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 245def8..4fd1c24 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -53,6 +53,7 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.BlurUtils;
@@ -274,13 +275,19 @@
collectFlow(
mView,
FlowKt.distinctUntilChanged(combineFlows(
- mKeyguardTransitionInteractor.isFinishedInStateWhere(
- KeyguardState::isBouncerState),
+ mKeyguardTransitionInteractor.isFinishedIn(
+ Scenes.Bouncer, KeyguardState.PRIMARY_BOUNCER),
+ mKeyguardTransitionInteractor.isFinishedIn(
+ KeyguardState.ALTERNATE_BOUNCER),
mShadeInteractor.isAnyExpanded(),
mCommunalInteractor.isCommunalShowing(),
- (anyBouncerShowing, shadeExpanded, communalShowing) -> {
- mAnyBouncerShowing = anyBouncerShowing;
- return anyBouncerShowing || shadeExpanded || communalShowing;
+ (primaryBouncerShowing,
+ alternateBouncerShowing,
+ shadeExpanded,
+ communalShowing) -> {
+ mAnyBouncerShowing = primaryBouncerShowing
+ || alternateBouncerShowing;
+ return mAnyBouncerShowing || shadeExpanded || communalShowing;
})),
mDreamManager::setDreamIsObscured,
mBackgroundDispatcher);
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
index 8a40c03..30a391e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
@@ -20,6 +20,11 @@
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.keyboardShortcutHelperRewrite
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
+import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter
import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
import dagger.Binds
@@ -37,6 +42,14 @@
@ClassKey(ShortcutHelperActivity::class)
fun activity(impl: ShortcutHelperActivity): Activity
+ @Binds
+ @SystemShortcuts
+ fun systemShortcutsSource(impl: SystemShortcutsSource): KeyboardShortcutGroupsSource
+
+ @Binds
+ @MultitaskingShortcuts
+ fun multitaskingShortcutsSource(impl: MultitaskingShortcutsSource): KeyboardShortcutGroupsSource
+
companion object {
@Provides
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt
new file mode 100644
index 0000000..8e94901
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.data.model
+
+import android.view.KeyboardShortcutInfo
+
+class KeyboardShortcutInfoBuilder(val label: String) {
+
+ private var modifiers = 0
+ private var keyCode = 0
+
+ fun command(modifiers: Int, keyCode: Int = 0) {
+ this.modifiers = modifiers
+ this.keyCode = keyCode
+ }
+
+ fun build() = KeyboardShortcutInfo(label, keyCode, modifiers)
+}
+
+fun shortcutInfo(label: String, block: KeyboardShortcutInfoBuilder.() -> Unit) =
+ KeyboardShortcutInfoBuilder(label).apply(block).build()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
index 04bde26..f54fd22 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
@@ -16,23 +16,128 @@
package com.android.systemui.keyboard.shortcut.data.repository
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import android.view.WindowManager
+import android.view.WindowManager.KeyboardShortcutsReceiver
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
-import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import javax.inject.Inject
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.suspendCancellableCoroutine
@SysUISingleton
class ShortcutHelperCategoriesRepository
@Inject
constructor(
- private val systemShortcutsSource: SystemShortcutsSource,
- private val multitaskingShortcutsSource: MultitaskingShortcutsSource,
+ @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource,
+ @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource,
+ private val windowManager: WindowManager,
+ shortcutHelperStateRepository: ShortcutHelperStateRepository
) {
- fun systemShortcutsCategory(): ShortcutCategory =
- systemShortcutsSource.systemShortcutsCategory()
+ val systemShortcutsCategory =
+ shortcutHelperStateRepository.state.map {
+ if (it is Active) {
+ toShortcutCategory(
+ systemShortcutsSource.shortcutGroups(),
+ ShortcutCategoryType.SYSTEM
+ )
+ } else {
+ null
+ }
+ }
- fun multitaskingShortcutsCategory(): ShortcutCategory =
- multitaskingShortcutsSource.multitaskingShortcutCategory()
+ val multitaskingShortcutsCategory =
+ shortcutHelperStateRepository.state.map {
+ if (it is Active) {
+ toShortcutCategory(multitaskingShortcutsSource.shortcutGroups(), MULTI_TASKING)
+ } else {
+ null
+ }
+ }
+
+ val imeShortcutsCategory =
+ shortcutHelperStateRepository.state.map {
+ if (it is Active) retrieveImeShortcuts(it.deviceId) else null
+ }
+
+ private suspend fun retrieveImeShortcuts(deviceId: Int): ShortcutCategory? {
+ return suspendCancellableCoroutine { continuation ->
+ val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups ->
+ continuation.resumeWith(Result.success(toShortcutCategory(shortcutGroups, IME)))
+ }
+ windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId)
+ }
+ }
+
+ private fun toShortcutCategory(
+ shortcutGroups: List<KeyboardShortcutGroup>,
+ type: ShortcutCategoryType,
+ ): ShortcutCategory? {
+ val subCategories =
+ shortcutGroups
+ .map { shortcutGroup ->
+ ShortcutSubCategory(
+ label = shortcutGroup.label.toString(),
+ shortcuts = toShortcuts(shortcutGroup.items)
+ )
+ }
+ .filter { it.shortcuts.isNotEmpty() }
+ return if (subCategories.isEmpty()) {
+ null
+ } else {
+ ShortcutCategory(type, subCategories)
+ }
+ }
+
+ private fun toShortcuts(infoList: List<KeyboardShortcutInfo>) =
+ infoList.mapNotNull { toShortcut(it) }
+
+ private fun toShortcut(shortcutInfo: KeyboardShortcutInfo): Shortcut? {
+ val shortcutCommand = toShortcutCommand(shortcutInfo)
+ return if (shortcutCommand == null) null
+ else Shortcut(label = shortcutInfo.label!!.toString(), commands = listOf(shortcutCommand))
+ }
+
+ private fun toShortcutCommand(info: KeyboardShortcutInfo): ShortcutCommand? {
+ val keyCodes = mutableListOf<Int>()
+ var remainingModifiers = info.modifiers
+ SUPPORTED_MODIFIERS.forEach { supportedModifier ->
+ if ((supportedModifier and remainingModifiers) != 0) {
+ keyCodes += supportedModifier
+ // "Remove" the modifier from the remaining modifiers
+ remainingModifiers = remainingModifiers and supportedModifier.inv()
+ }
+ }
+ if (remainingModifiers != 0) {
+ // There is a remaining modifier we don't support
+ return null
+ }
+ keyCodes += info.keycode
+ return ShortcutCommand(keyCodes)
+ }
+
+ companion object {
+ private val SUPPORTED_MODIFIERS =
+ listOf(
+ KeyEvent.META_META_ON,
+ KeyEvent.META_CTRL_ON,
+ KeyEvent.META_ALT_ON,
+ KeyEvent.META_SHIFT_ON,
+ KeyEvent.META_SYM_ON,
+ KeyEvent.META_FUNCTION_ON
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
new file mode 100644
index 0000000..0aced8c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.data.repository
+
+import android.content.Context
+import android.view.KeyEvent.KEYCODE_ALT_LEFT
+import android.view.KeyEvent.KEYCODE_ALT_RIGHT
+import android.view.KeyEvent.KEYCODE_BACK
+import android.view.KeyEvent.KEYCODE_BREAK
+import android.view.KeyEvent.KEYCODE_BUTTON_A
+import android.view.KeyEvent.KEYCODE_BUTTON_B
+import android.view.KeyEvent.KEYCODE_BUTTON_C
+import android.view.KeyEvent.KEYCODE_BUTTON_L1
+import android.view.KeyEvent.KEYCODE_BUTTON_L2
+import android.view.KeyEvent.KEYCODE_BUTTON_MODE
+import android.view.KeyEvent.KEYCODE_BUTTON_R1
+import android.view.KeyEvent.KEYCODE_BUTTON_R2
+import android.view.KeyEvent.KEYCODE_BUTTON_SELECT
+import android.view.KeyEvent.KEYCODE_BUTTON_START
+import android.view.KeyEvent.KEYCODE_BUTTON_X
+import android.view.KeyEvent.KEYCODE_BUTTON_Y
+import android.view.KeyEvent.KEYCODE_BUTTON_Z
+import android.view.KeyEvent.KEYCODE_CTRL_LEFT
+import android.view.KeyEvent.KEYCODE_CTRL_RIGHT
+import android.view.KeyEvent.KEYCODE_DEL
+import android.view.KeyEvent.KEYCODE_DPAD_CENTER
+import android.view.KeyEvent.KEYCODE_DPAD_DOWN
+import android.view.KeyEvent.KEYCODE_DPAD_LEFT
+import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
+import android.view.KeyEvent.KEYCODE_DPAD_UP
+import android.view.KeyEvent.KEYCODE_EISU
+import android.view.KeyEvent.KEYCODE_ENTER
+import android.view.KeyEvent.KEYCODE_EQUALS
+import android.view.KeyEvent.KEYCODE_ESCAPE
+import android.view.KeyEvent.KEYCODE_F1
+import android.view.KeyEvent.KEYCODE_F10
+import android.view.KeyEvent.KEYCODE_F11
+import android.view.KeyEvent.KEYCODE_F12
+import android.view.KeyEvent.KEYCODE_F2
+import android.view.KeyEvent.KEYCODE_F3
+import android.view.KeyEvent.KEYCODE_F4
+import android.view.KeyEvent.KEYCODE_F5
+import android.view.KeyEvent.KEYCODE_F6
+import android.view.KeyEvent.KEYCODE_F7
+import android.view.KeyEvent.KEYCODE_F8
+import android.view.KeyEvent.KEYCODE_F9
+import android.view.KeyEvent.KEYCODE_FORWARD_DEL
+import android.view.KeyEvent.KEYCODE_GRAVE
+import android.view.KeyEvent.KEYCODE_HENKAN
+import android.view.KeyEvent.KEYCODE_HOME
+import android.view.KeyEvent.KEYCODE_INSERT
+import android.view.KeyEvent.KEYCODE_KATAKANA_HIRAGANA
+import android.view.KeyEvent.KEYCODE_MEDIA_FAST_FORWARD
+import android.view.KeyEvent.KEYCODE_MEDIA_NEXT
+import android.view.KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
+import android.view.KeyEvent.KEYCODE_MEDIA_PREVIOUS
+import android.view.KeyEvent.KEYCODE_MEDIA_REWIND
+import android.view.KeyEvent.KEYCODE_MEDIA_STOP
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.KEYCODE_MOVE_END
+import android.view.KeyEvent.KEYCODE_MOVE_HOME
+import android.view.KeyEvent.KEYCODE_MUHENKAN
+import android.view.KeyEvent.KEYCODE_NUMPAD_0
+import android.view.KeyEvent.KEYCODE_NUMPAD_1
+import android.view.KeyEvent.KEYCODE_NUMPAD_2
+import android.view.KeyEvent.KEYCODE_NUMPAD_3
+import android.view.KeyEvent.KEYCODE_NUMPAD_4
+import android.view.KeyEvent.KEYCODE_NUMPAD_5
+import android.view.KeyEvent.KEYCODE_NUMPAD_6
+import android.view.KeyEvent.KEYCODE_NUMPAD_7
+import android.view.KeyEvent.KEYCODE_NUMPAD_8
+import android.view.KeyEvent.KEYCODE_NUMPAD_9
+import android.view.KeyEvent.KEYCODE_NUMPAD_ADD
+import android.view.KeyEvent.KEYCODE_NUMPAD_COMMA
+import android.view.KeyEvent.KEYCODE_NUMPAD_DIVIDE
+import android.view.KeyEvent.KEYCODE_NUMPAD_DOT
+import android.view.KeyEvent.KEYCODE_NUMPAD_ENTER
+import android.view.KeyEvent.KEYCODE_NUMPAD_EQUALS
+import android.view.KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN
+import android.view.KeyEvent.KEYCODE_NUMPAD_MULTIPLY
+import android.view.KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN
+import android.view.KeyEvent.KEYCODE_NUMPAD_SUBTRACT
+import android.view.KeyEvent.KEYCODE_NUM_LOCK
+import android.view.KeyEvent.KEYCODE_PAGE_DOWN
+import android.view.KeyEvent.KEYCODE_PAGE_UP
+import android.view.KeyEvent.KEYCODE_PERIOD
+import android.view.KeyEvent.KEYCODE_SCROLL_LOCK
+import android.view.KeyEvent.KEYCODE_SHIFT_LEFT
+import android.view.KeyEvent.KEYCODE_SHIFT_RIGHT
+import android.view.KeyEvent.KEYCODE_SPACE
+import android.view.KeyEvent.KEYCODE_SYSRQ
+import android.view.KeyEvent.KEYCODE_TAB
+import android.view.KeyEvent.KEYCODE_ZENKAKU_HANKAKU
+import android.view.KeyEvent.META_ALT_ON
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_FUNCTION_ON
+import android.view.KeyEvent.META_META_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyEvent.META_SYM_ON
+import com.android.systemui.res.R
+
+object ShortcutHelperKeys {
+
+ val keyIcons =
+ mapOf(
+ META_META_ON to R.drawable.ic_ksh_key_meta,
+ )
+
+ val specialKeyLabels =
+ mapOf<Int, (Context) -> String>(
+ KEYCODE_HOME to { context -> context.getString(R.string.keyboard_key_home) },
+ KEYCODE_BACK to { context -> context.getString(R.string.keyboard_key_back) },
+ KEYCODE_DPAD_UP to { context -> context.getString(R.string.keyboard_key_dpad_up) },
+ KEYCODE_DPAD_DOWN to { context -> context.getString(R.string.keyboard_key_dpad_down) },
+ KEYCODE_DPAD_LEFT to { context -> context.getString(R.string.keyboard_key_dpad_left) },
+ KEYCODE_DPAD_RIGHT to
+ { context ->
+ context.getString(R.string.keyboard_key_dpad_right)
+ },
+ KEYCODE_DPAD_CENTER to
+ { context ->
+ context.getString(R.string.keyboard_key_dpad_center)
+ },
+ KEYCODE_PERIOD to { "." },
+ KEYCODE_TAB to { context -> context.getString(R.string.keyboard_key_tab) },
+ KEYCODE_SPACE to { context -> context.getString(R.string.keyboard_key_space) },
+ KEYCODE_ENTER to { context -> context.getString(R.string.keyboard_key_enter) },
+ KEYCODE_DEL to { context -> context.getString(R.string.keyboard_key_backspace) },
+ KEYCODE_MEDIA_PLAY_PAUSE to
+ { context ->
+ context.getString(R.string.keyboard_key_media_play_pause)
+ },
+ KEYCODE_MEDIA_STOP to
+ { context ->
+ context.getString(R.string.keyboard_key_media_stop)
+ },
+ KEYCODE_MEDIA_NEXT to
+ { context ->
+ context.getString(R.string.keyboard_key_media_next)
+ },
+ KEYCODE_MEDIA_PREVIOUS to
+ { context ->
+ context.getString(R.string.keyboard_key_media_previous)
+ },
+ KEYCODE_MEDIA_REWIND to
+ { context ->
+ context.getString(R.string.keyboard_key_media_rewind)
+ },
+ KEYCODE_MEDIA_FAST_FORWARD to
+ { context ->
+ context.getString(R.string.keyboard_key_media_fast_forward)
+ },
+ KEYCODE_PAGE_UP to { context -> context.getString(R.string.keyboard_key_page_up) },
+ KEYCODE_PAGE_DOWN to { context -> context.getString(R.string.keyboard_key_page_down) },
+ KEYCODE_BUTTON_A to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "A")
+ },
+ KEYCODE_BUTTON_B to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "B")
+ },
+ KEYCODE_BUTTON_C to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "C")
+ },
+ KEYCODE_BUTTON_X to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "X")
+ },
+ KEYCODE_BUTTON_Y to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "Y")
+ },
+ KEYCODE_BUTTON_Z to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "Z")
+ },
+ KEYCODE_BUTTON_L1 to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "L1")
+ },
+ KEYCODE_BUTTON_R1 to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "R1")
+ },
+ KEYCODE_BUTTON_L2 to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "L2")
+ },
+ KEYCODE_BUTTON_R2 to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "R2")
+ },
+ KEYCODE_BUTTON_START to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "Start")
+ },
+ KEYCODE_BUTTON_SELECT to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "Select")
+ },
+ KEYCODE_BUTTON_MODE to
+ { context ->
+ context.getString(R.string.keyboard_key_button_template, "Mode")
+ },
+ KEYCODE_FORWARD_DEL to
+ { context ->
+ context.getString(R.string.keyboard_key_forward_del)
+ },
+ KEYCODE_ESCAPE to { "Esc" },
+ KEYCODE_SYSRQ to { "SysRq" },
+ KEYCODE_BREAK to { "Break" },
+ KEYCODE_SCROLL_LOCK to { "Scroll Lock" },
+ KEYCODE_MOVE_HOME to { context -> context.getString(R.string.keyboard_key_move_home) },
+ KEYCODE_MOVE_END to { context -> context.getString(R.string.keyboard_key_move_end) },
+ KEYCODE_INSERT to { context -> context.getString(R.string.keyboard_key_insert) },
+ KEYCODE_F1 to { "F1" },
+ KEYCODE_F2 to { "F2" },
+ KEYCODE_F3 to { "F3" },
+ KEYCODE_F4 to { "F4" },
+ KEYCODE_F5 to { "F5" },
+ KEYCODE_F6 to { "F6" },
+ KEYCODE_F7 to { "F7" },
+ KEYCODE_F8 to { "F8" },
+ KEYCODE_F9 to { "F9" },
+ KEYCODE_F10 to { "F10" },
+ KEYCODE_F11 to { "F11" },
+ KEYCODE_F12 to { "F12" },
+ KEYCODE_NUM_LOCK to { context -> context.getString(R.string.keyboard_key_num_lock) },
+ KEYCODE_MINUS to { "-" },
+ KEYCODE_GRAVE to { "`" },
+ KEYCODE_EQUALS to { "=" },
+ KEYCODE_NUMPAD_0 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "0")
+ },
+ KEYCODE_NUMPAD_1 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "1")
+ },
+ KEYCODE_NUMPAD_2 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "2")
+ },
+ KEYCODE_NUMPAD_3 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "3")
+ },
+ KEYCODE_NUMPAD_4 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "4")
+ },
+ KEYCODE_NUMPAD_5 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "5")
+ },
+ KEYCODE_NUMPAD_6 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "6")
+ },
+ KEYCODE_NUMPAD_7 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "7")
+ },
+ KEYCODE_NUMPAD_8 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "8")
+ },
+ KEYCODE_NUMPAD_9 to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "9")
+ },
+ KEYCODE_NUMPAD_DIVIDE to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "/")
+ },
+ KEYCODE_NUMPAD_MULTIPLY to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "*")
+ },
+ KEYCODE_NUMPAD_SUBTRACT to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "-")
+ },
+ KEYCODE_NUMPAD_ADD to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "+")
+ },
+ KEYCODE_NUMPAD_DOT to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, ".")
+ },
+ KEYCODE_NUMPAD_COMMA to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, ",")
+ },
+ KEYCODE_NUMPAD_ENTER to
+ { context ->
+ context.getString(
+ R.string.keyboard_key_numpad_template,
+ context.getString(R.string.keyboard_key_enter)
+ )
+ },
+ KEYCODE_NUMPAD_EQUALS to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "=")
+ },
+ KEYCODE_NUMPAD_LEFT_PAREN to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, "(")
+ },
+ KEYCODE_NUMPAD_RIGHT_PAREN to
+ { context ->
+ context.getString(R.string.keyboard_key_numpad_template, ")")
+ },
+ KEYCODE_ZENKAKU_HANKAKU to { "半角/全角" },
+ KEYCODE_EISU to { "英数" },
+ KEYCODE_MUHENKAN to { "無変換" },
+ KEYCODE_HENKAN to { "変換" },
+ KEYCODE_KATAKANA_HIRAGANA to { "かな" },
+ KEYCODE_ALT_LEFT to { "Alt" },
+ KEYCODE_ALT_RIGHT to { "Alt" },
+ KEYCODE_CTRL_LEFT to { "Ctrl" },
+ KEYCODE_CTRL_RIGHT to { "Ctrl" },
+ KEYCODE_SHIFT_LEFT to { "Shift" },
+ KEYCODE_SHIFT_RIGHT to { "Shift" },
+
+ // Modifiers
+ META_META_ON to { "Meta" },
+ META_CTRL_ON to { "Ctrl" },
+ META_ALT_ON to { "Alt" },
+ META_SHIFT_ON to { "Shift" },
+ META_SYM_ON to { "Sym" },
+ META_FUNCTION_ON to { "Fn" },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt
new file mode 100644
index 0000000..1e2b333
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+
+interface KeyboardShortcutGroupsSource {
+
+ fun shortcutGroups(): List<KeyboardShortcutGroup>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index 7b64f87..f4022a0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -25,53 +25,53 @@
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyboardShortcutGroup
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING
-import com.android.systemui.keyboard.shortcut.shared.model.shortcut
-import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
import javax.inject.Inject
-class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) {
+class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+ KeyboardShortcutGroupsSource {
- fun multitaskingShortcutCategory() =
- shortcutCategory(MULTI_TASKING) {
- subCategory(
+ override fun shortcutGroups() =
+ listOf(
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcutHelper_category_recent_apps),
recentsShortcuts()
- )
- subCategory(
+ ),
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcutHelper_category_split_screen),
splitScreenShortcuts()
)
- }
+ )
private fun splitScreenShortcuts() =
listOf(
// Enter Split screen with current app to RHS:
// - Meta + Ctrl + Right arrow
- shortcut(resources.getString(R.string.system_multitasking_rhs)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_RIGHT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_rhs)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_RIGHT)
},
// Enter Split screen with current app to LHS:
// - Meta + Ctrl + Left arrow
- shortcut(resources.getString(R.string.system_multitasking_lhs)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_LEFT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_lhs)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_LEFT)
},
// Switch from Split screen to full screen:
// - Meta + Ctrl + Up arrow
- shortcut(resources.getString(R.string.system_multitasking_full_screen)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_UP)
+ shortcutInfo(resources.getString(R.string.system_multitasking_full_screen)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
},
// Change split screen focus to RHS:
// - Meta + Alt + Right arrow
- shortcut(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
- command(META_META_ON, META_ALT_ON, KEYCODE_DPAD_RIGHT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
+ command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_RIGHT)
},
// Change split screen focus to LHS:
// - Meta + Alt + Left arrow
- shortcut(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
- command(META_META_ON, META_ALT_ON, KEYCODE_DPAD_LEFT)
+ shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
+ command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
},
)
@@ -79,13 +79,13 @@
listOf(
// Cycle through recent apps (forward):
// - Alt + Tab
- shortcut(resources.getString(R.string.group_system_cycle_forward)) {
+ shortcutInfo(resources.getString(R.string.group_system_cycle_forward)) {
command(META_ALT_ON, KEYCODE_TAB)
},
// Cycle through recent apps (back):
// - Shift + Alt + Tab
- shortcut(resources.getString(R.string.group_system_cycle_back)) {
- command(META_SHIFT_ON, META_ALT_ON, KEYCODE_TAB)
+ shortcutInfo(resources.getString(R.string.group_system_cycle_back)) {
+ command(META_SHIFT_ON or META_ALT_ON, KEYCODE_TAB)
},
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
index 51c67df..6cd2d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
@@ -31,73 +31,79 @@
import android.view.KeyEvent.KEYCODE_TAB
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
+import android.view.KeyboardShortcutGroup
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.SYSTEM
-import com.android.systemui.keyboard.shortcut.shared.model.shortcut
-import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
import javax.inject.Inject
-class SystemShortcutsSource @Inject constructor(@Main private val resources: Resources) {
+class SystemShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+ KeyboardShortcutGroupsSource {
- fun systemShortcutsCategory() =
- shortcutCategory(SYSTEM) {
- subCategory(
+ override fun shortcutGroups() =
+ listOf(
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcut_helper_category_system_controls),
systemControlsShortcuts()
- )
- subCategory(
+ ),
+ KeyboardShortcutGroup(
resources.getString(R.string.shortcut_helper_category_system_apps),
systemAppsShortcuts()
)
- }
+ )
private fun systemControlsShortcuts() =
listOf(
// Access list of all apps and search (i.e. Search/Launcher):
// - Meta
- shortcut(resources.getString(R.string.group_system_access_all_apps_search)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_all_apps_search)) {
command(META_META_ON)
},
// Access home screen:
// - Meta + H
// - Meta + Enter
- shortcut(resources.getString(R.string.group_system_access_home_screen)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
command(META_META_ON, KEYCODE_H)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
command(META_META_ON, KEYCODE_ENTER)
},
// Overview of open apps:
// - Meta + Tab
- shortcut(resources.getString(R.string.group_system_overview_open_apps)) {
+ shortcutInfo(resources.getString(R.string.group_system_overview_open_apps)) {
command(META_META_ON, KEYCODE_TAB)
},
// Back: go back to previous state (back button)
// - Meta + Escape OR
// - Meta + Backspace OR
// - Meta + Left arrow
- shortcut(resources.getString(R.string.group_system_go_back)) {
+ shortcutInfo(resources.getString(R.string.group_system_go_back)) {
command(META_META_ON, KEYCODE_ESCAPE)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_go_back)) {
command(META_META_ON, KEYCODE_DEL)
+ },
+ shortcutInfo(resources.getString(R.string.group_system_go_back)) {
command(META_META_ON, KEYCODE_DPAD_LEFT)
},
// Take a full screenshot:
// - Meta + Ctrl + S
- shortcut(resources.getString(R.string.group_system_full_screenshot)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_S)
+ shortcutInfo(resources.getString(R.string.group_system_full_screenshot)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_S)
},
// Access list of system / apps shortcuts:
// - Meta + /
- shortcut(resources.getString(R.string.group_system_access_system_app_shortcuts)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_system_app_shortcuts)) {
command(META_META_ON, KEYCODE_SLASH)
},
// Access notification shade:
// - Meta + N
- shortcut(resources.getString(R.string.group_system_access_notification_shade)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_notification_shade)) {
command(META_META_ON, KEYCODE_N)
},
// Lock screen:
// - Meta + L
- shortcut(resources.getString(R.string.group_system_lock_screen)) {
+ shortcutInfo(resources.getString(R.string.group_system_lock_screen)) {
command(META_META_ON, KEYCODE_L)
},
)
@@ -106,17 +112,17 @@
listOf(
// Pull up Notes app for quick memo:
// - Meta + Ctrl + N
- shortcut(resources.getString(R.string.group_system_quick_memo)) {
- command(META_META_ON, META_CTRL_ON, KEYCODE_N)
+ shortcutInfo(resources.getString(R.string.group_system_quick_memo)) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_N)
},
// Access system settings:
// - Meta + I
- shortcut(resources.getString(R.string.group_system_access_system_settings)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_system_settings)) {
command(META_META_ON, KEYCODE_I)
},
// Access Assistant:
// - Meta + A
- shortcut(resources.getString(R.string.group_system_access_google_assistant)) {
+ shortcutInfo(resources.getString(R.string.group_system_access_google_assistant)) {
command(META_META_ON, KEYCODE_A)
},
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
index 883407c..ead10e5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
@@ -18,30 +18,50 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperCategoriesRepository
-import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
@SysUISingleton
class ShortcutHelperCategoriesInteractor
@Inject
constructor(
- stateRepository: ShortcutHelperStateRepository,
categoriesRepository: ShortcutHelperCategoriesRepository,
) {
+ private val systemsShortcutCategory = categoriesRepository.systemShortcutsCategory
+ private val multitaskingShortcutsCategory = categoriesRepository.multitaskingShortcutsCategory
+ private val imeShortcutsCategory = categoriesRepository.imeShortcutsCategory
+
val shortcutCategories: Flow<List<ShortcutCategory>> =
- stateRepository.state.map { state ->
- when (state) {
- is ShortcutHelperState.Active ->
- listOf(
- categoriesRepository.systemShortcutsCategory(),
- categoriesRepository.multitaskingShortcutsCategory()
- )
- is ShortcutHelperState.Inactive -> emptyList()
- }
+ combine(systemsShortcutCategory, multitaskingShortcutsCategory, imeShortcutsCategory) {
+ shortcutCategories ->
+ shortcutCategories.filterNotNull().map { groupSubCategoriesInCategory(it) }
}
+
+ private fun groupSubCategoriesInCategory(shortcutCategory: ShortcutCategory): ShortcutCategory {
+ val subCategoriesWithGroupedShortcuts =
+ shortcutCategory.subCategories.map {
+ ShortcutSubCategory(
+ label = it.label,
+ shortcuts = groupShortcutsInSubcategory(it.shortcuts)
+ )
+ }
+ return ShortcutCategory(
+ type = shortcutCategory.type,
+ subCategories = subCategoriesWithGroupedShortcuts
+ )
+ }
+
+ private fun groupShortcutsInSubcategory(shortcuts: List<Shortcut>) =
+ shortcuts
+ .groupBy { it.label }
+ .entries
+ .map { (commonLabel, groupedShortcuts) ->
+ Shortcut(label = commonLabel, commands = groupedShortcuts.flatMap { it.commands })
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperStateInteractor.kt
index 3d707f7..299628e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperStateInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperStateInteractor.kt
@@ -26,6 +26,7 @@
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
@SysUISingleton
@@ -38,7 +39,7 @@
private val repository: ShortcutHelperStateRepository
) {
- val state: Flow<ShortcutHelperState> = repository.state
+ val state: Flow<ShortcutHelperState> = repository.state.asStateFlow()
fun onViewClosed() {
repository.hide()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt
new file mode 100644
index 0000000..479299c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class MultitaskingShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt
new file mode 100644
index 0000000..1bcc2b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class SystemShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
index c5e8d2c..3ac7fa8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
@@ -19,6 +19,7 @@
enum class ShortcutCategoryType {
SYSTEM,
MULTI_TASKING,
+ IME
}
data class ShortcutCategory(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index a7e2633..5f6fe1c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -105,6 +105,13 @@
const val UNLOCK_ANIMATION_DURATION_MS = 167L
/**
+ * If there are two different wallpapers on home and lock screen, duration and delay of the lock
+ * wallpaper fade out.
+ */
+const val LOCK_WALLPAPER_FADE_OUT_DURATION = 140L
+const val LOCK_WALLPAPER_FADE_OUT_START_DELAY = 0L
+
+/**
* How long the in-window launcher icon animation takes. This is used if the launcher is underneath
* the lock screen and supports in-window animations.
*
@@ -115,23 +122,24 @@
/**
* How long to wait for the shade to get out of the way before starting the canned unlock animation.
+ * If there are two different wallpapers on home and lock screen, this is also the duration and
+ * delay of the home wallpaper fade in.
*/
const val LEGACY_CANNED_UNLOCK_START_DELAY = 100L
-const val CANNED_UNLOCK_START_DELAY = 67L
+const val CANNED_UNLOCK_START_DELAY = 25L
/**
* Duration for the alpha animation on the surface behind. This plays to fade in the surface during
* a swipe to unlock (and to fade it back out if the swipe is cancelled).
*/
-const val LEGACY_SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 175L
-const val SURFACE_BEHIND_FADE_OUT_DURATION_MS = 83L
+const val SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 175L
/**
* Start delay for the surface behind animation, used so that the lockscreen can get out of the way
* before the surface begins appearing.
*/
const val LEGACY_UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS = 75L
-const val SURFACE_BEHIND_FADE_OUT_START_DELAY_MS = 0L
+const val UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS = 67L
/**
* Initiates, controls, and ends the keyguard unlock animation.
@@ -268,7 +276,8 @@
@VisibleForTesting
var surfaceTransactionApplier: SyncRtSurfaceTransactionApplier? = null
private var surfaceBehindRemoteAnimationTargets: Array<RemoteAnimationTarget>? = null
- private var wallpaperTargets: Array<RemoteAnimationTarget>? = null
+ private var openingWallpaperTargets: Array<RemoteAnimationTarget>? = null
+ private var closingWallpaperTargets: Array<RemoteAnimationTarget>? = null
private var surfaceBehindRemoteAnimationStartTime: Long = 0
/**
@@ -286,6 +295,8 @@
var wallpaperCannedUnlockAnimator = ValueAnimator.ofFloat(0f, 1f)
+ var wallpaperFadeOutUnlockAnimator = ValueAnimator.ofFloat(1f, 0f)
+
/**
* Matrix applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
* app/launcher behind the keyguard.
@@ -335,7 +346,7 @@
init {
with(surfaceBehindAlphaAnimator) {
- duration = surfaceBehindFadeOutDurationMs()
+ duration = SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
interpolator = Interpolators.LINEAR
addUpdateListener { valueAnimator: ValueAnimator ->
surfaceBehindAlpha = valueAnimator.animatedValue as Float
@@ -351,7 +362,8 @@
if (surfaceBehindAlpha == 0f) {
Log.d(TAG, "surfaceBehindAlphaAnimator#onAnimationEnd")
surfaceBehindRemoteAnimationTargets = null
- wallpaperTargets = null
+ openingWallpaperTargets = null
+ closingWallpaperTargets = null
keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
false /* cancelled */)
} else {
@@ -367,8 +379,10 @@
else LAUNCHER_ICONS_ANIMATION_DURATION_MS
interpolator = if (fasterUnlockTransition()) Interpolators.LINEAR
else Interpolators.ALPHA_OUT
+ if (fasterUnlockTransition()) startDelay = CANNED_UNLOCK_START_DELAY
addUpdateListener { valueAnimator: ValueAnimator ->
- setWallpaperAppearAmount(valueAnimator.animatedValue as Float)
+ setWallpaperAppearAmount(
+ valueAnimator.animatedValue as Float, openingWallpaperTargets)
}
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
@@ -379,6 +393,18 @@
})
}
+ if (fasterUnlockTransition()) {
+ with(wallpaperFadeOutUnlockAnimator) {
+ duration = LOCK_WALLPAPER_FADE_OUT_DURATION
+ startDelay = LOCK_WALLPAPER_FADE_OUT_START_DELAY
+ interpolator = Interpolators.LINEAR
+ addUpdateListener { valueAnimator: ValueAnimator ->
+ setWallpaperAppearAmount(
+ valueAnimator.animatedValue as Float, closingWallpaperTargets)
+ }
+ }
+ }
+
with(surfaceBehindEntryAnimator) {
duration = unlockAnimationDurationMs()
startDelay = surfaceBehindFadeOutStartDelayMs()
@@ -546,7 +572,8 @@
*/
fun notifyStartSurfaceBehindRemoteAnimation(
targets: Array<RemoteAnimationTarget>,
- wallpapers: Array<RemoteAnimationTarget>,
+ openingWallpapers: Array<RemoteAnimationTarget>,
+ closingWallpapers: Array<RemoteAnimationTarget>,
startTime: Long,
requestedShowSurfaceBehindKeyguard: Boolean
) {
@@ -556,7 +583,8 @@
}
surfaceBehindRemoteAnimationTargets = targets
- wallpaperTargets = wallpapers
+ openingWallpaperTargets = openingWallpapers
+ closingWallpaperTargets = closingWallpapers
surfaceBehindRemoteAnimationStartTime = startTime
// If we specifically requested that the surface behind be made visible (vs. it being made
@@ -720,8 +748,9 @@
return@postDelayed
}
- if ((wallpaperTargets?.isNotEmpty() == true)) {
+ if ((openingWallpaperTargets?.isNotEmpty() == true)) {
fadeInWallpaper()
+ if (fasterUnlockTransition()) fadeOutWallpaper()
hideKeyguardViewAfterRemoteAnimation()
} else {
keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
@@ -855,7 +884,8 @@
/**
* Scales in and translates up the surface behind the keyguard. This is used during unlock
* animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
- * cancelled).
+ * cancelled). When called with [wallpapers]=true, if there are different home and lock screen
+ * wallpapers, this transitions between the two wallpapers
*/
fun setSurfaceBehindAppearAmount(amount: Float, wallpapers: Boolean = true) {
val animationAlpha = when {
@@ -923,13 +953,27 @@
}
if (wallpapers) {
- setWallpaperAppearAmount(amount)
+ if (!fasterUnlockTransition()) setWallpaperAppearAmount(amount, openingWallpaperTargets)
+ else {
+ // Use the amount to compute the fadeInAmount and fadeOutAmount of the home and lock
+ // screen wallpapers to manually imitate the canned unlock animation.
+ val total = (UNLOCK_ANIMATION_DURATION_MS + CANNED_UNLOCK_START_DELAY).toFloat()
+ val fadeInStart = CANNED_UNLOCK_START_DELAY / total
+ val fadeInAmount = maxOf(0f, (amount - fadeInStart) / (1f - fadeInStart))
+
+ val fadeOutStart = LOCK_WALLPAPER_FADE_OUT_START_DELAY / total
+ val fadeOutEnd = fadeOutStart + LOCK_WALLPAPER_FADE_OUT_DURATION / total
+ val fadeOutAmount = ((amount - fadeOutStart) / (fadeOutEnd - fadeOutStart))
+ .coerceIn(0f, 1f)
+
+ setWallpaperAppearAmount(fadeInAmount, openingWallpaperTargets)
+ setWallpaperAppearAmount(1 - fadeOutAmount, closingWallpaperTargets)
+ }
}
}
- fun setWallpaperAppearAmount(amount: Float) {
+ fun setWallpaperAppearAmount(amount: Float, wallpaperTargets: Array<RemoteAnimationTarget>?) {
val animationAlpha = amount
-
wallpaperTargets?.forEach { wallpaper ->
// SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
// unable to draw
@@ -991,7 +1035,8 @@
// That target is no longer valid since the animation finished, null it out.
surfaceBehindRemoteAnimationTargets = null
- wallpaperTargets = null
+ openingWallpaperTargets = null
+ if (fasterUnlockTransition()) closingWallpaperTargets = null
playingCannedUnlockAnimation = false
dismissAmountThresholdsReached = false
@@ -1035,6 +1080,12 @@
wallpaperCannedUnlockAnimator.start()
}
+ private fun fadeOutWallpaper() {
+ Log.d(TAG, "fadeOutWallpaper")
+ wallpaperFadeOutUnlockAnimator.cancel()
+ wallpaperFadeOutUnlockAnimator.start()
+ }
+
private fun fadeOutSurfaceBehind() {
Log.d(TAG, "fadeOutSurfaceBehind")
surfaceBehindAlphaAnimator.cancel()
@@ -1165,17 +1216,8 @@
* Temporary method for b/298186160
* TODO (b/298186160) replace references with the constant itself when flag is removed
*/
- private fun surfaceBehindFadeOutDurationMs(): Long {
- return if (fasterUnlockTransition()) SURFACE_BEHIND_FADE_OUT_DURATION_MS
- else LEGACY_SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
- }
-
- /**
- * Temporary method for b/298186160
- * TODO (b/298186160) replace references with the constant itself when flag is removed
- */
private fun surfaceBehindFadeOutStartDelayMs(): Long {
- return if (fasterUnlockTransition()) SURFACE_BEHIND_FADE_OUT_START_DELAY_MS
+ return if (fasterUnlockTransition()) UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS
else LEGACY_UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 36b7ed2..1ea5d1c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -42,6 +42,7 @@
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.Flags.notifyPowerManagerUserActivityBackground;
import static com.android.systemui.Flags.refactorGetCurrentUser;
+import static com.android.systemui.Flags.translucentOccludingActivityFix;
import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
import android.animation.Animator;
@@ -1036,6 +1037,17 @@
(int) (fullWidth - initialWidth) /* left */,
fullWidth /* right */,
mWindowCornerRadius, mWindowCornerRadius);
+ } else if (translucentOccludingActivityFix()
+ && mOccludingRemoteAnimationTarget != null
+ && mOccludingRemoteAnimationTarget.isTranslucent) {
+ // Animating in a transparent window looks really weird. Just let it be
+ // fullscreen and the app can do an internal animation if it wants to.
+ return new TransitionAnimator.State(
+ 0,
+ fullHeight,
+ 0,
+ fullWidth,
+ 0f, 0f);
} else {
final float initialHeight = fullHeight / 2f;
final float initialWidth = fullWidth / 2f;
@@ -1399,6 +1411,11 @@
private final Lazy<DreamViewModel> mDreamViewModel;
private final Lazy<CommunalTransitionViewModel> mCommunalTransitionViewModel;
private RemoteAnimationTarget mRemoteAnimationTarget;
+
+ /**
+ * The most recent RemoteAnimationTarget provided for an occluding activity animation.
+ */
+ private RemoteAnimationTarget mOccludingRemoteAnimationTarget;
private boolean mShowCommunalWhenUnoccluding = false;
private final Lazy<WindowManagerLockscreenVisibilityManager> mWmLockscreenVisibilityManager;
@@ -3143,9 +3160,13 @@
w -> w.mode == RemoteAnimationTarget.MODE_OPENING).toArray(
RemoteAnimationTarget[]::new);
+ RemoteAnimationTarget[] closingWallpapers = Arrays.stream(wallpapers).filter(
+ w -> w.mode == RemoteAnimationTarget.MODE_CLOSING).toArray(
+ RemoteAnimationTarget[]::new);
+
mKeyguardUnlockAnimationControllerLazy.get()
.notifyStartSurfaceBehindRemoteAnimation(
- openingApps, openingWallpapers, startTime,
+ openingApps, openingWallpapers, closingWallpapers, startTime,
mSurfaceBehindRemoteAnimationRequested);
} else {
mInteractionJankMonitor.begin(
@@ -3937,6 +3958,13 @@
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
+ // Save mRemoteAnimationTarget for reference in the animation controller. Needs to be
+ // called prior to super.onAnimationStart() since that's the call that eventually asks
+ // the animation controller to configure the animation state.
+ if (apps.length > 0) {
+ mOccludingRemoteAnimationTarget = apps[0];
+ }
+
super.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
mInteractionJankMonitor.begin(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
index 0863cd7..80675d3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
@@ -28,8 +28,6 @@
const val CREATE_NOTE = "create_note"
const val DO_NOT_DISTURB = "do_not_disturb"
const val FLASHLIGHT = "flashlight"
- // TODO(b/339667383): delete or properly implement this once a product decision is made
- const val GLANCEABLE_HUB = "glanceable_hub"
const val HOME_CONTROLS = "home"
const val MUTE = "mute"
const val QR_CODE_SCANNER = "qr_code_scanner"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
deleted file mode 100644
index 5d54126..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.keyguard.data.quickaffordance
-
-import com.android.systemui.Flags
-import com.android.systemui.animation.Expandable
-import com.android.systemui.common.shared.model.ContentDescription
-import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.communal.data.repository.CommunalSceneRepository
-import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.res.R
-import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flowOf
-
-/** Shortcut that opens the glanceable hub. */
-// TODO(b/339667383): delete or properly implement this once a product decision is made
-@SysUISingleton
-class GlanceableHubQuickAffordanceConfig
-@Inject
-constructor(
- private val communalRepository: CommunalSceneRepository,
-) : KeyguardQuickAffordanceConfig {
-
- override val key: String = BuiltInKeyguardQuickAffordanceKeys.GLANCEABLE_HUB
-
- override fun pickerName(): String = "Glanceable hub"
-
- override val pickerIconResourceId = R.drawable.ic_widgets
-
- override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> by lazy {
- if (Flags.glanceableHubShortcutButton()) {
- val contentDescription = ContentDescription.Loaded(pickerName())
- val icon = Icon.Resource(pickerIconResourceId, contentDescription)
- flowOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon))
- } else {
- flowOf(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
- }
- }
-
- override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
- return KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
- }
-
- override fun onTriggered(
- expandable: Expandable?
- ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
- communalRepository.changeScene(CommunalScenes.Communal, null)
- return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
index 93296f0..4556195 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
@@ -36,7 +36,6 @@
camera: CameraQuickAffordanceConfig,
doNotDisturb: DoNotDisturbQuickAffordanceConfig,
flashlight: FlashlightQuickAffordanceConfig,
- glanceableHub: GlanceableHubQuickAffordanceConfig,
home: HomeControlsKeyguardQuickAffordanceConfig,
mute: MuteQuickAffordanceConfig,
quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
@@ -47,7 +46,6 @@
camera,
doNotDisturb,
flashlight,
- glanceableHub,
home,
mute,
quickAccessWallet,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
index 0748979..796374a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
@@ -20,7 +20,6 @@
import android.content.Context
import android.content.IntentFilter
import android.content.SharedPreferences
-import com.android.systemui.Flags
import com.android.systemui.backup.BackupHelper
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -30,7 +29,6 @@
import com.android.systemui.res.R
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
-import com.android.systemui.util.settings.SystemSettings
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
@@ -52,7 +50,6 @@
@Application private val context: Context,
private val userFileManager: UserFileManager,
private val userTracker: UserTracker,
- private val systemSettings: SystemSettings,
broadcastDispatcher: BroadcastDispatcher,
) : KeyguardQuickAffordanceSelectionManager {
@@ -73,22 +70,6 @@
}
private val defaults: Map<String, List<String>> by lazy {
- // Quick hack to allow testing out a lock screen shortcut to open the glanceable hub. This
- // flag will not be rolled out and is only used for local testing.
- // TODO(b/339667383): delete or properly implement this once a product decision is made
- if (Flags.glanceableHubShortcutButton()) {
- if (systemSettings.getBool("open_hub_chip_replace_home_controls", false)) {
- return@lazy mapOf(
- "bottom_start" to listOf("glanceable_hub"),
- "bottom_end" to listOf("create_note")
- )
- } else {
- return@lazy mapOf(
- "bottom_start" to listOf("home"),
- "bottom_end" to listOf("glanceable_hub")
- )
- }
- }
context.resources
.getStringArray(R.array.config_keyguardQuickAffordanceDefaults)
.associate { item ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index b3d9a76..56b520e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -59,7 +59,7 @@
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
- override fun pickerName(): String = context.getString(R.string.accessibility_wallet_button)
+ override fun pickerName(): String = context.getString(R.string.wallet_title)
override val pickerIconResourceId = R.drawable.ic_wallet_lockscreen
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index 888d047..63dd255 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.data.repository
import android.graphics.Point
+import com.android.internal.widget.LockPatternUtils
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.biometrics.AuthController
@@ -321,6 +322,7 @@
private val systemClock: SystemClock,
facePropertyRepository: FacePropertyRepository,
private val userTracker: UserTracker,
+ lockPatternUtils: LockPatternUtils,
) : KeyguardRepository {
private val _dismissAction: MutableStateFlow<DismissAction> =
MutableStateFlow(DismissAction.None)
@@ -478,7 +480,8 @@
awaitClose { keyguardStateController.removeCallback(callback) }
}
- private val _isKeyguardEnabled = MutableStateFlow(true)
+ private val _isKeyguardEnabled =
+ MutableStateFlow(!lockPatternUtils.isLockScreenDisabled(userTracker.userId))
override val isKeyguardEnabled: StateFlow<Boolean> = _isKeyguardEnabled.asStateFlow()
private val _isDozing = MutableStateFlow(statusBarStateController.isDozing)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 506a18d..b423ed9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -17,10 +17,8 @@
package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
-import android.app.DreamManager
import com.android.app.animation.Interpolators
import com.android.systemui.communal.domain.interactor.CommunalInteractor
-import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -53,10 +51,8 @@
keyguardInteractor: KeyguardInteractor,
powerInteractor: PowerInteractor,
private val communalInteractor: CommunalInteractor,
- private val communalSceneInteractor: CommunalSceneInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
val deviceEntryRepository: DeviceEntryRepository,
- private val dreamManager: DreamManager,
) :
TransitionInteractor(
fromState = KeyguardState.DOZING,
@@ -123,8 +119,7 @@
.filterRelevantKeyguardStateAnd { isAwake -> isAwake }
.sample(
keyguardInteractor.isKeyguardOccluded,
- communalInteractor.isCommunalAvailable,
- communalSceneInteractor.isIdleOnCommunal,
+ communalInteractor.isIdleOnCommunal,
canTransitionToGoneOnWake,
keyguardInteractor.primaryBouncerShowing,
)
@@ -132,7 +127,6 @@
(
_,
occluded,
- isCommunalAvailable,
isIdleOnCommunal,
canTransitionToGoneOnWake,
primaryBouncerShowing) ->
@@ -147,10 +141,6 @@
KeyguardState.OCCLUDED
} else if (isIdleOnCommunal) {
KeyguardState.GLANCEABLE_HUB
- } else if (isCommunalAvailable && dreamManager.canStartDreaming(true)) {
- // This case handles tapping the power button to transition through
- // dream -> off -> hub.
- KeyguardState.GLANCEABLE_HUB
} else {
KeyguardState.LOCKSCREEN
}
@@ -169,8 +159,7 @@
powerInteractor.detailedWakefulness
.filterRelevantKeyguardStateAnd { it.isAwake() }
.sample(
- communalInteractor.isCommunalAvailable,
- communalSceneInteractor.isIdleOnCommunal,
+ communalInteractor.isIdleOnCommunal,
keyguardInteractor.biometricUnlockState,
canTransitionToGoneOnWake,
keyguardInteractor.primaryBouncerShowing,
@@ -178,7 +167,6 @@
.collect {
(
_,
- isCommunalAvailable,
isIdleOnCommunal,
biometricUnlockState,
canDismissLockscreen,
@@ -200,10 +188,6 @@
KeyguardState.PRIMARY_BOUNCER
} else if (isIdleOnCommunal) {
KeyguardState.GLANCEABLE_HUB
- } else if (isCommunalAvailable && dreamManager.canStartDreaming(true)) {
- // This case handles tapping the power button to transition through
- // dream -> off -> hub.
- KeyguardState.GLANCEABLE_HUB
} else {
KeyguardState.LOCKSCREEN
},
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index ab1194e..22ab82b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -51,7 +51,6 @@
import com.android.systemui.statusbar.notification.NotificationUtils.interpolate
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
-import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
@@ -251,13 +250,17 @@
/** Keyguard can be clipped at the top as the shade is dragged */
val topClippingBounds: Flow<Int?> by lazy {
- repository.topClippingBounds
- .sampleFilter(
+ combineTransform(
keyguardTransitionInteractor
.transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
- .onStart { emit(0f) }
- ) { goneValue ->
- goneValue != 1f
+ .map { it == 1f }
+ .onStart { emit(false) }
+ .distinctUntilChanged(),
+ repository.topClippingBounds
+ ) { isGone, topClippingBounds ->
+ if (!isGone) {
+ emit(topClippingBounds)
+ }
}
.distinctUntilChanged()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
index bb6215a..7a06d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
@@ -32,6 +32,7 @@
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.res.R
+import com.android.systemui.shade.PulsingGestureListener
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -51,10 +52,10 @@
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-/** Business logic for use-cases related to the keyguard long-press feature. */
+/** Business logic for use-cases related to top-level touch handling in the lock screen. */
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
-class KeyguardLongPressInteractor
+class KeyguardTouchHandlingInteractor
@Inject
constructor(
@Application private val appContext: Context,
@@ -65,6 +66,7 @@
private val featureFlags: FeatureFlags,
broadcastDispatcher: BroadcastDispatcher,
private val accessibilityManager: AccessibilityManagerWrapper,
+ private val pulsingGestureListener: PulsingGestureListener,
) {
/** Whether the long-press handling feature should be enabled. */
val isLongPressHandlingEnabled: StateFlow<Boolean> =
@@ -166,6 +168,16 @@
_shouldOpenSettings.value = false
}
+ /** Notifies that the lockscreen has been clicked at position [x], [y]. */
+ fun onClick(x: Float, y: Float) {
+ pulsingGestureListener.onSingleTapUp(x, y)
+ }
+
+ /** Notifies that the lockscreen has been double clicked. */
+ fun onDoubleClick() {
+ pulsingGestureListener.onDoubleTapEvent()
+ }
+
private fun showSettings() {
_shouldOpenSettings.value = true
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 37272dc..2d389aa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -530,17 +530,23 @@
return finishedKeyguardState.map { stateMatcher(it) }.distinctUntilChanged()
}
- /** Whether we've FINISHED a transition to a state that matches the given predicate. */
- fun isFinishedInState(state: KeyguardState): Flow<Boolean> {
- return finishedKeyguardState.map { it == state }.distinctUntilChanged()
+ fun isFinishedIn(scene: SceneKey, stateWithoutSceneContainer: KeyguardState): Flow<Boolean> {
+ return if (SceneContainerFlag.isEnabled) {
+ sceneInteractor
+ .get()
+ .transitionState
+ .map { it.isIdle(scene) || it.isTransitioning(from = scene) }
+ .distinctUntilChanged()
+ } else {
+ isFinishedIn(stateWithoutSceneContainer)
+ }
}
- /**
- * Whether we've FINISHED a transition to a state that matches the given predicate. Consider
- * using [isFinishedInStateWhere] whenever possible instead
- */
- fun isFinishedInStateWhereValue(stateMatcher: (KeyguardState) -> Boolean) =
- stateMatcher(finishedKeyguardState.replayCache.last())
+ /** Whether we've FINISHED a transition to a state */
+ fun isFinishedIn(state: KeyguardState): Flow<Boolean> {
+ state.checkValidState()
+ return finishedKeyguardState.map { it == state }.distinctUntilChanged()
+ }
fun getCurrentState(): KeyguardState {
return currentKeyguardState.replayCache.last()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
index 6a2bb5f..8db6a43 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
@@ -15,7 +15,9 @@
*/
package com.android.systemui.keyguard.shared.model
+import android.util.Log
import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
/** List of all possible states to transition to/from */
@@ -87,6 +89,22 @@
/** An activity is displaying over the keyguard. */
OCCLUDED;
+ fun checkValidState() {
+ val isStateValid: Boolean
+ val isEnabled: String
+ if (SceneContainerFlag.isEnabled) {
+ isStateValid = this === mapToSceneContainerState()
+ isEnabled = "enabled"
+ } else {
+ isStateValid = this !== UNDEFINED
+ isEnabled = "disabled"
+ }
+
+ if (!isStateValid) {
+ Log.e("KeyguardState", "$this is not a valid state when scene container is $isEnabled")
+ }
+ }
+
fun mapToSceneContainerState(): KeyguardState {
return when (this) {
OFF,
@@ -128,17 +146,12 @@
return state != GONE
}
- /** Whether either of the bouncers are visible when we're FINISHED in the given state. */
- @JvmStatic
- fun isBouncerState(state: KeyguardState): Boolean {
- return state == PRIMARY_BOUNCER || state == ALTERNATE_BOUNCER
- }
-
/**
* Whether the device is awake ([PowerInteractor.isAwake]) when we're FINISHED in the given
* keyguard state.
*/
fun deviceIsAwakeInState(state: KeyguardState): Boolean {
+ state.checkValidState()
return when (state) {
OFF -> false
DOZING -> false
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
index f2821a0..e063380 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
@@ -37,6 +37,10 @@
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.AodClockBurnInModel
import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.util.ui.value
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
object KeyguardClockViewBinder {
@@ -99,15 +103,20 @@
launch {
if (!MigrateClocksToBlueprint.isEnabled) return@launch
- viewModel.isAodIconsVisible.collect {
- viewModel.currentClock.value?.let {
- if (
- viewModel.isLargeClockVisible.value && it.config.useCustomClockScene
- ) {
- blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
+ combine(
+ viewModel.hasAodIcons,
+ rootViewModel.isNotifIconContainerVisible.map { it.value }
+ ) { hasIcon, isVisible ->
+ hasIcon && isVisible
+ }
+ .distinctUntilChanged()
+ .collect { _ ->
+ viewModel.currentClock.value?.let {
+ if (it.config.useCustomClockScene) {
+ blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
+ }
}
}
- }
}
launch {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
index 09fe067..057b4f9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
@@ -22,7 +22,7 @@
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launch
import com.android.systemui.common.ui.view.LongPressHandlingView
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
@@ -39,7 +39,7 @@
@JvmStatic
fun bind(
view: LongPressHandlingView,
- viewModel: KeyguardLongPressViewModel,
+ viewModel: KeyguardTouchHandlingViewModel,
onSingleTap: () -> Unit,
falsingManager: FalsingManager,
) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
index fa57565..4150ceb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
@@ -26,9 +26,9 @@
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.common.ui.binder.TextViewBinder
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils
import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils.LAUNCH_SOURCE_KEYGUARD
import com.android.systemui.lifecycle.repeatWhenAttached
@@ -44,7 +44,7 @@
fun bind(
view: View,
viewModel: KeyguardSettingsMenuViewModel,
- longPressViewModel: KeyguardLongPressViewModel,
+ touchHandlingViewModel: KeyguardTouchHandlingViewModel,
rootViewModel: KeyguardRootViewModel?,
vibratorHelper: VibratorHelper,
activityStarter: ActivityStarter
@@ -97,7 +97,7 @@
val hitRect = Rect()
view.getHitRect(hitRect)
if (!hitRect.contains(point.x, point.y)) {
- longPressViewModel.onTouchedOutside()
+ touchHandlingViewModel.onTouchedOutside()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 777c873..4f0ac42 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -197,8 +197,7 @@
initiallySelectedSlotId =
bundle.getString(
KeyguardPreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
- )
- ?: KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ ) ?: KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
shouldHighlightSelectedAffordance = shouldHighlightSelectedAffordance,
)
} else {
@@ -230,8 +229,7 @@
val previewContext =
display?.let {
ContextThemeWrapper(context.createDisplayContext(it), context.getTheme())
- }
- ?: context
+ } ?: context
val rootView = FrameLayout(previewContext)
@@ -318,8 +316,8 @@
*/
private fun setUpSmartspace(previewContext: Context, parentView: ViewGroup) {
if (
- !lockscreenSmartspaceController.isEnabled() ||
- !lockscreenSmartspaceController.isDateWeatherDecoupled()
+ !lockscreenSmartspaceController.isEnabled ||
+ !lockscreenSmartspaceController.isDateWeatherDecoupled
) {
return
}
@@ -654,6 +652,7 @@
clockController.clock = clock
}
}
+
private fun onClockChanged() {
if (MigrateClocksToBlueprint.isEnabled) {
return
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
index 34a1da5..0637bba 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
@@ -45,6 +45,7 @@
import com.android.systemui.plugins.clocks.ClockFaceLayout
import com.android.systemui.res.R
import com.android.systemui.shared.R as sharedR
+import com.android.systemui.util.ui.value
import dagger.Lazy
import javax.inject.Inject
@@ -70,6 +71,7 @@
private val rootViewModel: KeyguardRootViewModel,
) : KeyguardSection() {
override fun addViews(constraintLayout: ConstraintLayout) {}
+
override fun bindData(constraintLayout: ConstraintLayout) {
if (!MigrateClocksToBlueprint.isEnabled) {
return
@@ -121,35 +123,39 @@
private fun getTargetClockFace(clock: ClockController): ClockFaceLayout =
if (keyguardClockViewModel.isLargeClockVisible.value) clock.largeClock.layout
else clock.smallClock.layout
+
private fun getNonTargetClockFace(clock: ClockController): ClockFaceLayout =
if (keyguardClockViewModel.isLargeClockVisible.value) clock.smallClock.layout
else clock.largeClock.layout
fun constrainWeatherClockDateIconsBarrier(constraints: ConstraintSet) {
constraints.apply {
- if (keyguardClockViewModel.isAodIconsVisible.value) {
+ createBarrier(
+ R.id.weather_clock_bc_smartspace_bottom,
+ Barrier.BOTTOM,
+ getDimen(ENHANCED_SMARTSPACE_HEIGHT),
+ (custR.id.weather_clock_time)
+ )
+ if (
+ rootViewModel.isNotifIconContainerVisible.value.value &&
+ keyguardClockViewModel.hasAodIcons.value
+ ) {
createBarrier(
R.id.weather_clock_date_and_icons_barrier_bottom,
Barrier.BOTTOM,
0,
- *intArrayOf(sharedR.id.bc_smartspace_view, R.id.aod_notification_icon_container)
+ *intArrayOf(
+ R.id.aod_notification_icon_container,
+ R.id.weather_clock_bc_smartspace_bottom
+ )
)
} else {
- if (smartspaceViewModel.bcSmartspaceVisibility.value == VISIBLE) {
- createBarrier(
- R.id.weather_clock_date_and_icons_barrier_bottom,
- Barrier.BOTTOM,
- 0,
- (sharedR.id.bc_smartspace_view)
- )
- } else {
- createBarrier(
- R.id.weather_clock_date_and_icons_barrier_bottom,
- Barrier.BOTTOM,
- getDimen(ENHANCED_SMARTSPACE_HEIGHT),
- (R.id.lockscreen_clock_view)
- )
- }
+ createBarrier(
+ R.id.weather_clock_date_and_icons_barrier_bottom,
+ Barrier.BOTTOM,
+ 0,
+ *intArrayOf(R.id.weather_clock_bc_smartspace_bottom)
+ )
}
}
}
@@ -198,6 +204,7 @@
companion object {
private const val DATE_WEATHER_VIEW_HEIGHT = "date_weather_view_height"
private const val ENHANCED_SMARTSPACE_HEIGHT = "enhanced_smartspace_height"
+
fun getDimen(context: Context, name: String): Int {
val res = context.packageManager.getResourcesForApplication(context.packageName)
val id = res.getIdentifier(name, "dimen", context.packageName)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
index 32e76d0..5cd5172 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
@@ -34,9 +34,9 @@
import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.binder.KeyguardSettingsViewBinder
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
@@ -48,7 +48,7 @@
constructor(
@Main private val resources: Resources,
private val keyguardSettingsMenuViewModel: KeyguardSettingsMenuViewModel,
- private val keyguardLongPressViewModel: KeyguardLongPressViewModel,
+ private val keyguardTouchHandlingViewModel: KeyguardTouchHandlingViewModel,
private val keyguardRootViewModel: KeyguardRootViewModel,
private val vibratorHelper: VibratorHelper,
private val activityStarter: ActivityStarter,
@@ -76,7 +76,7 @@
KeyguardSettingsViewBinder.bind(
constraintLayout.requireViewById<View>(R.id.keyguard_settings_button),
keyguardSettingsMenuViewModel,
- keyguardLongPressViewModel,
+ keyguardTouchHandlingViewModel,
keyguardRootViewModel,
vibratorHelper,
activityStarter,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt
index a17c5e5..b33d552 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt
@@ -35,7 +35,7 @@
) : KeyguardSection() {
override fun addViews(constraintLayout: ConstraintLayout) {
if (!MigrateClocksToBlueprint.isEnabled) return
- if (smartspaceController.isEnabled()) return
+ if (smartspaceController.isEnabled) return
constraintLayout.findViewById<View?>(R.id.keyguard_slice_view)?.let {
(it.parent as ViewGroup).removeView(it)
@@ -47,7 +47,7 @@
override fun applyConstraints(constraintSet: ConstraintSet) {
if (!MigrateClocksToBlueprint.isEnabled) return
- if (smartspaceController.isEnabled()) return
+ if (smartspaceController.isEnabled) return
constraintSet.apply {
connect(
@@ -82,7 +82,7 @@
override fun removeViews(constraintLayout: ConstraintLayout) {
if (!MigrateClocksToBlueprint.isEnabled) return
- if (smartspaceController.isEnabled()) return
+ if (smartspaceController.isEnabled) return
constraintLayout.removeView(R.id.keyguard_slice_view)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt
index 4128c52..5cf100e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt
@@ -34,8 +34,8 @@
alternateBouncerInteractor: AlternateBouncerInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
) {
- val canShowAlternateBouncer: Flow<Boolean> = alternateBouncerInteractor.canShowAlternateBouncer
-
+ private val deviceSupportsAlternateBouncer: Flow<Boolean> =
+ alternateBouncerInteractor.alternateBouncerSupported
private val isTransitioningToOrFromOrShowingAlternateBouncer: Flow<Boolean> =
keyguardTransitionInteractor
.transitionValue(KeyguardState.ALTERNATE_BOUNCER)
@@ -43,8 +43,8 @@
.distinctUntilChanged()
val alternateBouncerWindowRequired: Flow<Boolean> =
- canShowAlternateBouncer.flatMapLatest { canShowAlternateBouncer ->
- if (canShowAlternateBouncer) {
+ deviceSupportsAlternateBouncer.flatMapLatest { deviceSupportsAlternateBouncer ->
+ if (deviceSupportsAlternateBouncer) {
isTransitioningToOrFromOrShowingAlternateBouncer
} else {
flowOf(false)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index 3e6f8e6..6fe51ae 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -44,7 +44,7 @@
private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
private val bottomAreaInteractor: KeyguardBottomAreaInteractor,
private val burnInHelperWrapper: BurnInHelperWrapper,
- private val longPressViewModel: KeyguardLongPressViewModel,
+ private val keyguardTouchHandlingViewModel: KeyguardTouchHandlingViewModel,
val settingsMenuViewModel: KeyguardSettingsMenuViewModel,
) {
data class PreviewMode(
@@ -162,7 +162,7 @@
* the lock screen settings menu item pop-up.
*/
fun onTouchedOutsideLockScreenSettingsMenu() {
- longPressViewModel.onTouchedOutside()
+ keyguardTouchHandlingViewModel.onTouchedOutside()
}
private fun button(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index f5c521a..573b75e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -31,7 +31,6 @@
import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
import com.android.systemui.statusbar.ui.SystemBarUtilsProxy
import javax.inject.Inject
@@ -50,7 +49,6 @@
keyguardClockInteractor: KeyguardClockInteractor,
@Application private val applicationScope: CoroutineScope,
aodNotificationIconViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
- notifsKeyguardInteractor: NotificationsKeyguardInteractor,
@get:VisibleForTesting val shadeInteractor: ShadeInteractor,
private val systemBarUtils: SystemBarUtilsProxy,
configurationInteractor: ConfigurationInteractor,
@@ -90,14 +88,13 @@
currentClock?.let { clock ->
val face = if (isLargeClock) clock.largeClock else clock.smallClock
face.config.hasCustomWeatherDataDisplay
- }
- ?: false
+ } ?: false
}
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = currentClock.value?.largeClock?.config?.hasCustomWeatherDataDisplay
- ?: false
+ initialValue =
+ currentClock.value?.largeClock?.config?.hasCustomWeatherDataDisplay ?: false
)
val clockShouldBeCentered: StateFlow<Boolean> =
@@ -109,15 +106,14 @@
// To translate elements below smartspace in weather clock to avoid overlapping between date
// element in weather clock and aod icons
- val isAodIconsVisible: StateFlow<Boolean> = combine(aodNotificationIconViewModel.icons.map {
- it.visibleIcons.isNotEmpty()
- }, notifsKeyguardInteractor.areNotificationsFullyHidden) { hasIcons, visible ->
- hasIcons && visible
- }.stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = false
- )
+ val hasAodIcons: StateFlow<Boolean> =
+ aodNotificationIconViewModel.icons
+ .map { it.visibleIcons.isNotEmpty() }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = false
+ )
val currentClockLayout: StateFlow<ClockLayout> =
combine(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index d7ac976..0fb29c2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -143,7 +143,7 @@
private val isOnLockscreen: Flow<Boolean> =
combine(
- keyguardTransitionInteractor.isFinishedInState(LOCKSCREEN).onStart { emit(false) },
+ keyguardTransitionInteractor.isFinishedIn(LOCKSCREEN).onStart { emit(false) },
anyOf(
keyguardTransitionInteractor.isInTransition(Edge.create(to = LOCKSCREEN)),
keyguardTransitionInteractor.isInTransition(Edge.create(from = LOCKSCREEN)),
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
index 66ceded..36a342b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
@@ -17,10 +17,10 @@
package com.android.systemui.keyguard.ui.viewmodel
-import com.android.systemui.res.R
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
-import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTouchHandlingInteractor
+import com.android.systemui.res.R
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -28,7 +28,7 @@
class KeyguardSettingsMenuViewModel
@Inject
constructor(
- private val interactor: KeyguardLongPressInteractor,
+ private val interactor: KeyguardTouchHandlingInteractor,
) {
val isVisible: Flow<Boolean> = interactor.isMenuVisible
val shouldOpenSettings: Flow<Boolean> = interactor.shouldOpenSettings
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
index c0b1f95..e30ddc6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
@@ -40,12 +40,12 @@
smartspaceInteractor: KeyguardSmartspaceInteractor,
) {
/** Whether the smartspace section is available in the build. */
- val isSmartspaceEnabled: Boolean = smartspaceController.isEnabled()
+ val isSmartspaceEnabled: Boolean = smartspaceController.isEnabled
/** Whether the weather area is available in the build. */
private val isWeatherEnabled: StateFlow<Boolean> = smartspaceInteractor.isWeatherEnabled
/** Whether the data and weather areas are decoupled in the build. */
- val isDateWeatherDecoupled: Boolean = smartspaceController.isDateWeatherDecoupled()
+ val isDateWeatherDecoupled: Boolean = smartspaceController.isDateWeatherDecoupled
/** Whether the date area should be visible. */
val isDateVisible: StateFlow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardTouchHandlingViewModel.kt
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardTouchHandlingViewModel.kt
index c73931a..f1cbf25 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardTouchHandlingViewModel.kt
@@ -18,16 +18,16 @@
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTouchHandlingInteractor
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
-/** Models UI state to support the lock screen long-press feature. */
+/** Models UI state to support top-level touch handling in the lock screen. */
@SysUISingleton
-class KeyguardLongPressViewModel
+class KeyguardTouchHandlingViewModel
@Inject
constructor(
- private val interactor: KeyguardLongPressInteractor,
+ private val interactor: KeyguardTouchHandlingInteractor,
) {
/** Whether the long-press handling feature should be enabled. */
@@ -45,4 +45,14 @@
fun onTouchedOutside() {
interactor.onTouchedOutside()
}
+
+ /** Notifies that the lockscreen has been clicked at position [x], [y]. */
+ fun onClick(x: Float, y: Float) {
+ interactor.onClick(x, y)
+ }
+
+ /** Notifies that the lockscreen has been double clicked. */
+ fun onDoubleClick() {
+ interactor.onDoubleClick()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
index b33eaa2..1de0abe 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
@@ -44,7 +44,7 @@
clockInteractor: KeyguardClockInteractor,
private val interactor: KeyguardBlueprintInteractor,
private val authController: AuthController,
- val longPress: KeyguardLongPressViewModel,
+ val touchHandling: KeyguardTouchHandlingViewModel,
val shadeInteractor: ShadeInteractor,
@Application private val applicationScope: CoroutineScope,
unfoldTransitionInteractor: UnfoldTransitionInteractor,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index 10cfd6b..630dcca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -53,7 +53,7 @@
deviceEntryInteractor: DeviceEntryInteractor,
communalInteractor: CommunalInteractor,
shadeInteractor: ShadeInteractor,
- val longPress: KeyguardLongPressViewModel,
+ val touchHandling: KeyguardTouchHandlingViewModel,
val notifications: NotificationsPlaceholderViewModel,
) {
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index c7fde48..52b0b87 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -674,4 +674,11 @@
return factory.create("DeviceEntryIconLog", 100);
}
+ /** Provides a {@link LogBuffer} for use by the volume loggers. */
+ @Provides
+ @SysUISingleton
+ @VolumeLog
+ public static LogBuffer provideVolumeLogBuffer(LogBufferFactory factory) {
+ return factory.create("VolumeLog", 50);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
index 939dab2..28bdbb2 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
@@ -20,13 +20,14 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.android.systemui.log.LogBuffer;
+import com.android.systemui.navigationbar.views.NavigationBar;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Qualifier;
-/** A {@link LogBuffer} for {@link com.android.systemui.navigationbar.NavigationBar}. */
+/** A {@link LogBuffer} for {@link NavigationBar}. */
@Qualifier
@Documented
@Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
index 46790a6..d09eeb2 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
@@ -19,13 +19,14 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.android.systemui.log.LogBuffer;
+import com.android.systemui.navigationbar.views.NavigationBar;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Qualifier;
-/** A {@link LogBuffer} for {@link com.android.systemui.navigationbar.NavigationBar}. */
+/** A {@link LogBuffer} for {@link NavigationBar}. */
@Qualifier
@Documented
@Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/VolumeLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/VolumeLog.kt
new file mode 100644
index 0000000..bc3858a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/VolumeLog.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger
+
+import javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for volume. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class VolumeLog
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index e7c2a45..bda0069 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -17,6 +17,7 @@
package com.android.systemui.media;
import android.annotation.Nullable;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -123,9 +124,13 @@
boolean looping, @Nullable VolumeShaper.Configuration volumeShaperConfig)
throws RemoteException {
if (LOGD) {
- Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
- + Binder.getCallingUid() + ")");
+ Log.d(TAG, "play(token=" + token + ", uri=" + uri
+ + ", uid=" + Binder.getCallingUid()
+ + ") uriUserId=" + ContentProvider.getUserIdFromUri(uri)
+ + " callingUserId=" + Binder.getCallingUserHandle().getIdentifier());
}
+ enforceUriUserId(uri);
+
Client client;
synchronized (mClients) {
client = mClients.get(token);
@@ -207,6 +212,7 @@
@Override
public String getTitle(Uri uri) {
+ enforceUriUserId(uri);
final UserHandle user = Binder.getCallingUserHandle();
return Ringtone.getTitle(getContextForUser(user), uri,
false /*followSettingsUri*/, false /*allowRemote*/);
@@ -239,6 +245,25 @@
}
throw new SecurityException("Uri is not ringtone, alarm, or notification: " + uri);
}
+
+ /**
+ * Must be called from the Binder calling thread.
+ * Ensures caller is from the same userId as the content they're trying to access.
+ * @param uri the URI to check
+ * @throws SecurityException when non-system call or userId in uri differs from the
+ * caller's userId
+ */
+ private void enforceUriUserId(Uri uri) throws SecurityException {
+ final int uriUserId = ContentProvider.getUserIdFromUri(uri);
+ final int callerUserId = Binder.getCallingUserHandle().getIdentifier();
+ // for a non-system call, verify the URI to play belongs to the same user as the caller
+ if (UserHandle.isApp(Binder.getCallingUid()) && uriUserId != callerUserId) {
+ throw new SecurityException("Illegal access to uri=" + uri
+ + " content associated with user=" + uriUserId
+ + ", request originates from user=" + callerUserId);
+ }
+ }
+
};
private Context getContextForUser(UserHandle user) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
index 846c596..69a157f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
@@ -585,7 +585,8 @@
/* intentSentUiThreadCallback = */ null,
buildLaunchAnimatorController(mMediaViewHolder.getPlayer()),
/* fillIntent = */ null,
- /* extraOptions = */ null);
+ /* extraOptions = */ null,
+ /* customMessage */ null);
} else {
try {
ActivityOptions opts = ActivityOptions.makeBasic();
diff --git a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
index c8e896d..5084944 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
@@ -84,9 +84,13 @@
SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to { it.scene != Scenes.Gone },
SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to
{
- it.scene == Scenes.Lockscreen ||
- it.scene == Scenes.NotificationsShade ||
- it.scene == Scenes.Shade
+ when {
+ it.invisibleDueToOcclusion -> false
+ it.scene == Scenes.Lockscreen -> true
+ it.scene == Scenes.NotificationsShade -> true
+ it.scene == Scenes.Shade -> true
+ else -> false
+ }
},
SYSUI_STATE_QUICK_SETTINGS_EXPANDED to
{
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 2e5ff9d..13a786a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -27,11 +27,11 @@
import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
import android.content.ContentResolver;
import android.content.Context;
@@ -74,10 +74,10 @@
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.rotation.RotationPolicyUtil;
+import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -573,7 +573,7 @@
}
}
- static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
+ public static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS;
if (isTransient) {
return MODE_SEMI_TRANSPARENT;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
index 4f713d6..abd8bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
@@ -24,6 +24,7 @@
import androidx.annotation.Nullable;
import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.navigationbar.views.NavigationBar;
import dagger.BindsInstance;
import dagger.Subcomponent;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index a601d7f..49fa3ba 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -19,7 +19,9 @@
import androidx.annotation.Nullable;
import com.android.internal.statusbar.RegisterStatusBarResult;
-import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
/** A controller to handle navigation bars. */
public interface NavigationBarController {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
index e73b078..c392c2f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
@@ -18,7 +18,9 @@
import com.android.internal.statusbar.RegisterStatusBarResult
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.phone.BarTransitions
+import com.android.systemui.shared.statusbar.phone.BarTransitions
+import com.android.systemui.navigationbar.views.NavigationBar
+import com.android.systemui.navigationbar.views.NavigationBarView
import javax.inject.Inject
/** A no-op version of [NavigationBarController] for variants like Arc and TV. */
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index 1c2a087..1dbdec9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -54,13 +54,15 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.settings.SecureSettings;
@@ -431,6 +433,8 @@
NavigationBar navBar = mNavigationBars.get(displayId);
if (navBar != null) {
navBar.checkNavBarModes();
+ } else {
+ mTaskbarDelegate.checkNavBarModes();
}
}
@@ -439,6 +443,8 @@
NavigationBar navBar = mNavigationBars.get(displayId);
if (navBar != null) {
navBar.finishBarAnimations();
+ } else {
+ mTaskbarDelegate.finishBarAnimations();
}
}
@@ -447,6 +453,8 @@
NavigationBar navBar = mNavigationBars.get(displayId);
if (navBar != null) {
navBar.touchAutoDim();
+ } else {
+ mTaskbarDelegate.touchAutoDim();
}
}
@@ -455,6 +463,8 @@
NavigationBar navBar = mNavigationBars.get(displayId);
if (navBar != null) {
navBar.transitionTo(barMode, animate);
+ } else {
+ mTaskbarDelegate.transitionTo(barMode, animate);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
index aab4fea..e2ba761 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
@@ -24,6 +24,8 @@
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.views.NavigationBarFrame;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.res.R;
import dagger.Module;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index b360af0..d022c1c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -24,6 +24,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
@@ -34,7 +35,6 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import android.app.StatusBarManager;
import android.app.StatusBarManager.WindowVisibleState;
@@ -63,13 +63,16 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -117,6 +120,11 @@
boolean longPressHomeEnabled) {
updateAssistantAvailability(available, longPressHomeEnabled);
}
+
+ @Override
+ public void updateWallpaperVisibility(boolean visible, int displayId) {
+ updateWallpaperVisible(displayId, visible);
+ }
};
private int mDisabledFlags;
private @WindowVisibleState int mTaskBarWindowState = WINDOW_STATE_SHOWING;
@@ -150,6 +158,7 @@
private final AutoHideUiElement mAutoHideUiElement = new AutoHideUiElement() {
@Override
public void synchronizeState() {
+ checkNavBarModes();
}
@Override
@@ -165,11 +174,13 @@
private BackAnimation mBackAnimation;
- private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final StatusBarStateController mStatusBarStateController;
@Inject
public TaskbarDelegate(Context context,
LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
- StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ StatusBarStateController statusBarStateController) {
mLightBarTransitionsControllerFactory = lightBarTransitionsControllerFactory;
mContext = context;
@@ -179,6 +190,7 @@
};
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mStatusBarKeyguardViewManager.setTaskbarDelegate(this);
+ mStatusBarStateController = statusBarStateController;
}
public void setDependencies(CommandQueue commandQueue,
@@ -324,6 +336,68 @@
return (mSysUiState.getFlags() & View.STATUS_BAR_DISABLE_RECENT) == 0;
}
+ void onTransitionModeUpdated(int barMode, boolean checkBarModes) {
+ if (mOverviewProxyService.getProxy() == null) {
+ return;
+ }
+
+ try {
+ mOverviewProxyService.getProxy().onTransitionModeUpdated(barMode, checkBarModes);
+ } catch (RemoteException e) {
+ Log.e(TAG, "onTransitionModeUpdated() failed, barMode: " + barMode, e);
+ }
+ }
+
+ void checkNavBarModes() {
+ if (mOverviewProxyService.getProxy() == null) {
+ return;
+ }
+
+ try {
+ mOverviewProxyService.getProxy().checkNavBarModes();
+ } catch (RemoteException e) {
+ Log.e(TAG, "checkNavBarModes() failed", e);
+ }
+ }
+
+ void finishBarAnimations() {
+ if (mOverviewProxyService.getProxy() == null) {
+ return;
+ }
+
+ try {
+ mOverviewProxyService.getProxy().finishBarAnimations();
+ } catch (RemoteException e) {
+ Log.e(TAG, "finishBarAnimations() failed", e);
+ }
+ }
+
+ void touchAutoDim() {
+ if (mOverviewProxyService.getProxy() == null) {
+ return;
+ }
+
+ try {
+ int state = mStatusBarStateController.getState();
+ boolean shouldReset =
+ state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED;
+ mOverviewProxyService.getProxy().touchAutoDim(shouldReset);
+ } catch (RemoteException e) {
+ Log.e(TAG, "touchAutoDim() failed", e);
+ }
+ }
+
+ void transitionTo(@BarTransitions.TransitionMode int barMode, boolean animate) {
+ if (mOverviewProxyService.getProxy() == null) {
+ return;
+ }
+
+ try {
+ mOverviewProxyService.getProxy().transitionTo(barMode, animate);
+ } catch (RemoteException e) {
+ Log.e(TAG, "transitionTo() failed, barMode: " + barMode, e);
+ }
+ }
private void updateAssistantAvailability(boolean assistantAvailable,
boolean longPressHomeEnabled) {
if (mOverviewProxyService.getProxy() == null) {
@@ -338,6 +412,18 @@
}
}
+ private void updateWallpaperVisible(int displayId, boolean visible) {
+ if (mOverviewProxyService.getProxy() == null) {
+ return;
+ }
+
+ try {
+ mOverviewProxyService.getProxy().updateWallpaperVisibility(displayId, visible);
+ } catch (RemoteException e) {
+ Log.e(TAG, "updateWallpaperVisibility() failed, visible: " + visible, e);
+ }
+ }
+
@Override
public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) {
@@ -465,9 +551,11 @@
private boolean updateTransitionMode(int barMode) {
if (mTransitionMode != barMode) {
mTransitionMode = barMode;
+ onTransitionModeUpdated(barMode, true);
if (mAutoHideController != null) {
mAutoHideController.touchAutoHide();
}
+
return true;
}
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
index d1ce1f6..1b985d20 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
@@ -32,7 +32,7 @@
import com.android.app.animation.Interpolators;
import com.android.settingslib.Utils;
-import com.android.systemui.navigationbar.buttons.ButtonInterface;
+import com.android.systemui.navigationbar.views.buttons.ButtonInterface;
import com.android.systemui.res.R;
public class NavigationHandle extends View implements ButtonInterface {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index 69aa450..e832abb 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
@@ -48,8 +48,8 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_WINDOW_STATE;
import static com.android.systemui.statusbar.phone.CentralSurfaces.dumpBarTransitions;
import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
@@ -117,11 +117,15 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.buttons.NavBarButtonClickLogger;
+import com.android.systemui.navigationbar.NavBarHelper;
import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.NavbarOrientationTrackingLogger;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -137,6 +141,7 @@
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.rotation.RotationPolicyUtil;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -149,7 +154,6 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -1992,7 +1996,7 @@
return mSamplingBounds;
}
- void setNavigationBarLumaSamplingEnabled(boolean enable) {
+ public void setNavigationBarLumaSamplingEnabled(boolean enable) {
if (enable) {
mRegionSamplingHelper.start(mSamplingBounds);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java
index 6c531d8..3388f93 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.view.MotionEvent.ACTION_OUTSIDE;
@@ -26,7 +26,7 @@
import android.view.MotionEvent;
import android.widget.FrameLayout;
-import com.android.systemui.navigationbar.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
public class NavigationBarFrame extends FrameLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
index 2ae0709..96b730c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
@@ -36,10 +36,11 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
-import com.android.systemui.navigationbar.buttons.ReverseLinearLayout;
-import com.android.systemui.navigationbar.buttons.ReverseLinearLayout.ReverseRelativeLayout;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout;
+import com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout.ReverseRelativeLayout;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.res.R;
import com.android.systemui.shared.system.QuickStepContract;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java
index 201e586..251745d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
@@ -25,10 +25,10 @@
import android.view.View;
import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
import com.android.systemui.res.R;
import com.android.systemui.settings.DisplayTracker;
-import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
index 2c6e297..0f36097 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.inputmethodservice.InputMethodService.canImeRenderGesturalNavButtons;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
@@ -66,12 +66,13 @@
import com.android.settingslib.Utils;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.ContextualButton;
-import com.android.systemui.navigationbar.buttons.ContextualButtonGroup;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
-import com.android.systemui.navigationbar.buttons.NearestTouchFrame;
+import com.android.systemui.navigationbar.ScreenPinningNotify;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.ContextualButton;
+import com.android.systemui.navigationbar.views.buttons.ContextualButtonGroup;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonDrawable;
+import com.android.systemui.navigationbar.views.buttons.NearestTouchFrame;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.recents.Recents;
import com.android.systemui.res.R;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java
index fc37b9f..6799a4f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static com.android.app.animation.Interpolators.LINEAR;
@@ -25,8 +25,6 @@
import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
-import com.android.systemui.navigationbar.NavBarButtonClickLogger;
-
import java.util.ArrayList;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java
index 5f8fafd..c1b4944 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.Nullable;
import android.graphics.drawable.Drawable;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java
index 517f8e7..5e6bfa8 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java
index 2ace303..c68d25f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.IdRes;
import android.annotation.NonNull;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java
index 8177fde..a6be314 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.animation.ObjectAnimator;
import android.content.res.Resources;
@@ -27,7 +27,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.res.R;
import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java
index 686facc..072a4db 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.animation.ArgbEvaluator;
import android.annotation.ColorInt;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java
index dbe87ea..1e85d6c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.KeyEvent.KEYCODE_UNKNOWN;
@@ -59,7 +59,6 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.NavBarButtonClickLogger;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.res.R;
import com.android.systemui.shared.navigationbar.KeyButtonRipple;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt
index 408acf3..ca58718 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar
+package com.android.systemui.navigationbar.views.buttons
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
index b1bd286..a5ba17b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar
+package com.android.systemui.navigationbar.views.buttons
import android.view.Surface
import com.android.systemui.log.LogBuffer
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java
index d780f7c..e1a1a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.content.Context;
import android.content.res.Configuration;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java
rename to packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java
index f1e1366..9d50bd6 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java
@@ -1,18 +1,20 @@
/*
* Copyright (C) 2016 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
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import android.annotation.Nullable;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
index c214361..ff20707 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
@@ -74,7 +74,7 @@
@Binds
@PaginatedBaseLayoutType
- fun bindPaginatedBaseGridLayout(impl: PartitionedGridLayout): PaginatableGridLayout
+ fun bindPaginatedBaseGridLayout(impl: InfiniteGridLayout): PaginatableGridLayout
@Binds
@PaginatedBaseLayoutType
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt
new file mode 100644
index 0000000..f7c71ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.data.repository
+
+import android.content.res.Resources
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
+import com.android.systemui.util.kotlin.emitOnStart
+import javax.inject.Inject
+import kotlinx.coroutines.flow.map
+
+@SysUISingleton
+class QuickQuickSettingsRowRepository
+@Inject
+constructor(
+ @Main private val resources: Resources,
+ configurationRepository: ConfigurationRepository,
+) {
+ val rows =
+ configurationRepository.onConfigurationChange.emitOnStart().map {
+ resources.getInteger(R.integer.quick_qs_panel_max_rows)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt
new file mode 100644
index 0000000..5f001df
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.data.repository.QuickQuickSettingsRowRepository
+import javax.inject.Inject
+
+@SysUISingleton
+class QuickQuickSettingsRowInteractor
+@Inject
+constructor(
+ quickQuickSettingsRowRepository: QuickQuickSettingsRowRepository,
+) {
+ val rows = quickQuickSettingsRowRepository.rows
+
+ val defaultRows = 2
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
new file mode 100644
index 0000000..007ec3a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+@file:OptIn(ExperimentalFoundationApi::class)
+
+package com.android.systemui.qs.panels.ui.compose
+
+import android.content.ClipData
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.draganddrop.dragAndDropSource
+import androidx.compose.foundation.draganddrop.dragAndDropTarget
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draganddrop.DragAndDropEvent
+import androidx.compose.ui.draganddrop.DragAndDropTarget
+import androidx.compose.ui.draganddrop.DragAndDropTransferData
+import androidx.compose.ui.draganddrop.mimeTypes
+import com.android.systemui.qs.pipeline.shared.TileSpec
+
+@Composable
+fun rememberDragAndDropState(listState: EditTileListState): DragAndDropState {
+ val sourceSpec: MutableState<TileSpec?> = remember { mutableStateOf(null) }
+ return remember(listState) { DragAndDropState(sourceSpec, listState) }
+}
+
+/**
+ * Holds the [TileSpec] of the tile being moved and modify the [EditTileListState] based on drag and
+ * drop events.
+ */
+class DragAndDropState(
+ val sourceSpec: MutableState<TileSpec?>,
+ private val listState: EditTileListState
+) {
+ /** Returns index of the dragged tile if it's present in the list. Returns -1 if not. */
+ fun currentPosition(): Int {
+ return sourceSpec.value?.let { listState.indexOf(it) } ?: -1
+ }
+
+ fun isMoving(tileSpec: TileSpec): Boolean {
+ return sourceSpec.value?.let { it == tileSpec } ?: false
+ }
+
+ fun onStarted(spec: TileSpec) {
+ sourceSpec.value = spec
+ }
+
+ fun onMoved(targetSpec: TileSpec) {
+ sourceSpec.value?.let { listState.move(it, targetSpec) }
+ }
+
+ fun onDrop() {
+ sourceSpec.value = null
+ }
+}
+
+/**
+ * Registers a tile as a [DragAndDropTarget] to receive drag events and update the
+ * [DragAndDropState] with the tile's position, which can be used to insert a temporary placeholder.
+ *
+ * @param dragAndDropState The [DragAndDropState] using the tiles list
+ * @param tileSpec The [TileSpec] of the tile
+ * @param acceptDrops Whether the tile should accept a drop based on a given [TileSpec]
+ * @param onDrop Action to be executed when a [TileSpec] is dropped on the tile
+ */
+@Composable
+fun Modifier.dragAndDropTile(
+ dragAndDropState: DragAndDropState,
+ tileSpec: TileSpec,
+ acceptDrops: (TileSpec) -> Boolean,
+ onDrop: (TileSpec, Int) -> Unit,
+): Modifier {
+ val target =
+ remember(dragAndDropState) {
+ object : DragAndDropTarget {
+ override fun onDrop(event: DragAndDropEvent): Boolean {
+ return dragAndDropState.sourceSpec.value?.let {
+ onDrop(it, dragAndDropState.currentPosition())
+ dragAndDropState.onDrop()
+ true
+ } ?: false
+ }
+
+ override fun onEntered(event: DragAndDropEvent) {
+ dragAndDropState.onMoved(tileSpec)
+ }
+ }
+ }
+ return dragAndDropTarget(
+ shouldStartDragAndDrop = { event ->
+ event.mimeTypes().contains(QsDragAndDrop.TILESPEC_MIME_TYPE) &&
+ dragAndDropState.sourceSpec.value?.let { acceptDrops(it) } ?: false
+ },
+ target = target,
+ )
+}
+
+/**
+ * Registers a tile list as a [DragAndDropTarget] to receive drop events. Use this on list
+ * containers to catch drops outside of tiles.
+ *
+ * @param dragAndDropState The [DragAndDropState] using the tiles list
+ * @param acceptDrops Whether the tile should accept a drop based on a given [TileSpec]
+ * @param onDrop Action to be executed when a [TileSpec] is dropped on the tile
+ */
+@Composable
+fun Modifier.dragAndDropTileList(
+ dragAndDropState: DragAndDropState,
+ acceptDrops: (TileSpec) -> Boolean,
+ onDrop: (TileSpec, Int) -> Unit,
+): Modifier {
+ val target =
+ remember(dragAndDropState) {
+ object : DragAndDropTarget {
+ override fun onDrop(event: DragAndDropEvent): Boolean {
+ return dragAndDropState.sourceSpec.value?.let {
+ onDrop(it, dragAndDropState.currentPosition())
+ dragAndDropState.onDrop()
+ true
+ } ?: false
+ }
+ }
+ }
+ return dragAndDropTarget(
+ target = target,
+ shouldStartDragAndDrop = { event ->
+ event.mimeTypes().contains(QsDragAndDrop.TILESPEC_MIME_TYPE) &&
+ dragAndDropState.sourceSpec.value?.let { acceptDrops(it) } ?: false
+ },
+ )
+}
+
+fun Modifier.dragAndDropTileSource(
+ tileSpec: TileSpec,
+ onTap: (TileSpec) -> Unit,
+ dragAndDropState: DragAndDropState
+): Modifier {
+ return dragAndDropSource {
+ detectTapGestures(
+ onTap = { onTap(tileSpec) },
+ onLongPress = {
+ dragAndDropState.onStarted(tileSpec)
+
+ // The tilespec from the ClipData transferred isn't actually needed as we're moving
+ // a tile within the same application. We're using a custom MIME type to limit the
+ // drag event to QS.
+ startTransfer(
+ DragAndDropTransferData(
+ ClipData(
+ QsDragAndDrop.CLIPDATA_LABEL,
+ arrayOf(QsDragAndDrop.TILESPEC_MIME_TYPE),
+ ClipData.Item(tileSpec.spec)
+ )
+ )
+ )
+ }
+ )
+ }
+}
+
+private object QsDragAndDrop {
+ const val CLIPDATA_LABEL = "tilespec"
+ const val TILESPEC_MIME_TYPE = "qstile/tilespec"
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
new file mode 100644
index 0000000..482c498
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.compose
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.snapshots.SnapshotStateList
+import androidx.compose.runtime.toMutableStateList
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+
+@Composable
+fun rememberEditListState(
+ tiles: List<EditTileViewModel>,
+): EditTileListState {
+ return remember(tiles) { EditTileListState(tiles) }
+}
+
+/** Holds the temporary state of the tile list during a drag movement where we move tiles around. */
+class EditTileListState(tiles: List<EditTileViewModel>) {
+ val tiles: SnapshotStateList<EditTileViewModel> = tiles.toMutableStateList()
+
+ fun move(tileSpec: TileSpec, target: TileSpec) {
+ val fromIndex = indexOf(tileSpec)
+ val toIndex = indexOf(target)
+
+ if (fromIndex == -1 || toIndex == -1 || fromIndex == toIndex) {
+ return
+ }
+
+ val isMovingToCurrent = tiles[toIndex].isCurrent
+ tiles.apply { add(toIndex, removeAt(fromIndex).copy(isCurrent = isMovingToCurrent)) }
+ }
+
+ fun indexOf(tileSpec: TileSpec): Int {
+ return tiles.indexOfFirst { it.tileSpec == tileSpec }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
index 7f5e474..092ad44 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
@@ -110,12 +110,15 @@
tiles: List<EditTileViewModel>,
modifier: Modifier,
onAddTile: (TileSpec, Int) -> Unit,
- onRemoveTile: (TileSpec) -> Unit
+ onRemoveTile: (TileSpec) -> Unit,
) {
val columns by viewModel.columns.collectAsStateWithLifecycle()
val showLabels by viewModel.showLabels.collectAsStateWithLifecycle()
- val (currentTiles, otherTiles) = tiles.partition { it.isCurrent }
+ val listState = rememberEditListState(tiles)
+ val dragAndDropState = rememberDragAndDropState(listState)
+
+ val (currentTiles, otherTiles) = listState.tiles.partition { it.isCurrent }
val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
onAddTile(it, CurrentTilesInteractor.POSITION_AT_END)
}
@@ -156,20 +159,24 @@
largeTileHeight = largeTileHeight,
iconTileHeight = iconTileHeight,
tilePadding = tilePadding,
- onRemoveTile = onRemoveTile,
+ onAdd = onAddTile,
+ onRemove = onRemoveTile,
isIconOnly = viewModel::isIconTile,
columns = columns,
showLabels = showLabels,
+ dragAndDropState = dragAndDropState,
)
AvailableTiles(
- tiles = otherTiles,
+ tiles = otherTiles.filter { !dragAndDropState.isMoving(it.tileSpec) },
largeTileHeight = largeTileHeight,
iconTileHeight = iconTileHeight,
tilePadding = tilePadding,
addTileToEnd = addTileToEnd,
+ onRemove = onRemoveTile,
isIconOnly = viewModel::isIconTile,
showLabels = showLabels,
columns = columns,
+ dragAndDropState = dragAndDropState,
)
}
}
@@ -194,10 +201,12 @@
largeTileHeight: Dp,
iconTileHeight: Dp,
tilePadding: Dp,
- onRemoveTile: (TileSpec) -> Unit,
+ onAdd: (TileSpec, Int) -> Unit,
+ onRemove: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
showLabels: Boolean,
columns: Int,
+ dragAndDropState: DragAndDropState,
) {
val (smallTiles, largeTiles) = tiles.partition { isIconOnly(it.tileSpec) }
@@ -207,29 +216,40 @@
CurrentTilesContainer {
TileLazyGrid(
columns = GridCells.Fixed(columns),
- modifier = Modifier.height(largeGridHeight),
+ modifier =
+ Modifier.height(largeGridHeight)
+ .dragAndDropTileList(dragAndDropState, { !isIconOnly(it) }, onAdd)
) {
editTiles(
- largeTiles,
- ClickAction.REMOVE,
- onRemoveTile,
- { false },
- indicatePosition = true
+ tiles = largeTiles,
+ clickAction = ClickAction.REMOVE,
+ onClick = onRemove,
+ isIconOnly = { false },
+ dragAndDropState = dragAndDropState,
+ acceptDrops = { !isIconOnly(it) },
+ onDrop = onAdd,
+ indicatePosition = true,
)
}
}
+
CurrentTilesContainer {
TileLazyGrid(
columns = GridCells.Fixed(columns),
- modifier = Modifier.height(smallGridHeight),
+ modifier =
+ Modifier.height(smallGridHeight)
+ .dragAndDropTileList(dragAndDropState, { isIconOnly(it) }, onAdd)
) {
editTiles(
- smallTiles,
- ClickAction.REMOVE,
- onRemoveTile,
- { true },
+ tiles = smallTiles,
+ clickAction = ClickAction.REMOVE,
+ onClick = onRemove,
+ isIconOnly = { true },
showLabels = showLabels,
- indicatePosition = true
+ dragAndDropState = dragAndDropState,
+ acceptDrops = { isIconOnly(it) },
+ onDrop = onAdd,
+ indicatePosition = true,
)
}
}
@@ -242,9 +262,11 @@
iconTileHeight: Dp,
tilePadding: Dp,
addTileToEnd: (TileSpec) -> Unit,
+ onRemove: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
showLabels: Boolean,
columns: Int,
+ dragAndDropState: DragAndDropState,
) {
val (tilesStock, tilesCustom) = tiles.partition { it.appName == null }
val (smallTiles, largeTiles) = tilesStock.partition { isIconOnly(it.tileSpec) }
@@ -258,13 +280,27 @@
val gridHeight =
largeGridHeight + smallGridHeight + largeGridHeightCustom + (tilePadding * 2)
+ val onDrop: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, _ ->
+ onRemove(tileSpec)
+ }
+
AvailableTilesContainer {
TileLazyGrid(
columns = GridCells.Fixed(columns),
- modifier = Modifier.height(gridHeight),
+ modifier =
+ Modifier.height(gridHeight)
+ .dragAndDropTileList(dragAndDropState, { true }, onDrop)
) {
// Large tiles
- editTiles(largeTiles, ClickAction.ADD, addTileToEnd, isIconOnly)
+ editTiles(
+ largeTiles,
+ ClickAction.ADD,
+ addTileToEnd,
+ isIconOnly,
+ dragAndDropState,
+ acceptDrops = { true },
+ onDrop = onDrop,
+ )
fillUpRow(nTiles = largeTiles.size, columns = columns / 2)
// Small tiles
@@ -273,7 +309,10 @@
ClickAction.ADD,
addTileToEnd,
isIconOnly,
- showLabels = showLabels
+ showLabels = showLabels,
+ dragAndDropState = dragAndDropState,
+ acceptDrops = { true },
+ onDrop = onDrop,
)
fillUpRow(nTiles = smallTiles.size, columns = columns)
@@ -283,7 +322,10 @@
ClickAction.ADD,
addTileToEnd,
isIconOnly,
- showLabels = showLabels
+ showLabels = showLabels,
+ dragAndDropState = dragAndDropState,
+ acceptDrops = { true },
+ onDrop = onDrop,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
new file mode 100644
index 0000000..c0371b9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.compose
+
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.GridItemSpan
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
+import com.android.systemui.res.R
+
+@Composable
+fun QuickQuickSettings(
+ viewModel: QuickQuickSettingsViewModel,
+ modifier: Modifier = Modifier,
+) {
+ val sizedTiles by
+ viewModel.tileViewModels.collectAsStateWithLifecycle(initialValue = emptyList())
+ val tiles = sizedTiles.map { it.tile }
+
+ DisposableEffect(tiles) {
+ val token = Any()
+ tiles.forEach { it.startListening(token) }
+ onDispose { tiles.forEach { it.stopListening(token) } }
+ }
+ val columns by viewModel.columns.collectAsStateWithLifecycle()
+
+ TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) {
+ items(
+ tiles.size,
+ key = { index -> sizedTiles[index].tile.spec },
+ span = { index -> GridItemSpan(sizedTiles[index].width) }
+ ) { index ->
+ Tile(
+ tile = tiles[index],
+ iconOnly = sizedTiles[index].width == 1,
+ modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
+ )
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
index bbb98d3..0bb4cfa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
@@ -74,12 +74,12 @@
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.Expandable
+import com.android.compose.modifiers.thenIf
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.common.ui.compose.load
import com.android.systemui.plugins.qs.QSTile
-import com.android.systemui.qs.panels.ui.viewmodel.AvailableEditActions
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileUiState
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
@@ -114,6 +114,7 @@
showLabels = showLabels,
label = state.label.toString(),
iconOnly = iconOnly,
+ clickEnabled = true,
onClick = tile::onClick,
onLongClick = tile::onLongClick,
modifier = modifier,
@@ -127,6 +128,7 @@
secondaryLabel = state.secondaryLabel.toString(),
icon = icon,
colors = colors,
+ clickEnabled = true,
onClick = tile::onSecondaryClick,
onLongClick = tile::onLongClick,
)
@@ -140,7 +142,7 @@
showLabels: Boolean,
label: String,
iconOnly: Boolean,
- clickEnabled: Boolean = true,
+ clickEnabled: Boolean = false,
onClick: (Expandable) -> Unit = {},
onLongClick: (Expandable) -> Unit = {},
modifier: Modifier = Modifier,
@@ -168,11 +170,12 @@
Box(
modifier =
Modifier.fillMaxSize()
- .combinedClickable(
- enabled = clickEnabled,
- onClick = { onClick(it) },
- onLongClick = { onLongClick(it) }
- )
+ .thenIf(clickEnabled) {
+ Modifier.combinedClickable(
+ onClick = { onClick(it) },
+ onLongClick = { onLongClick(it) }
+ )
+ }
.tilePadding(),
) {
content()
@@ -197,7 +200,7 @@
secondaryLabel: String?,
icon: Icon,
colors: TileColors,
- clickEnabled: Boolean = true,
+ clickEnabled: Boolean = false,
onClick: (Expandable) -> Unit = {},
onLongClick: (Expandable) -> Unit = {},
) {
@@ -212,13 +215,12 @@
) {
Box(
modifier =
- Modifier.fillMaxSize()
- .clip(TileDefaults.TileShape)
- .combinedClickable(
- enabled = clickEnabled,
+ Modifier.fillMaxSize().clip(TileDefaults.TileShape).thenIf(clickEnabled) {
+ Modifier.combinedClickable(
onClick = { onClick(it) },
onLongClick = { onLongClick(it) }
)
+ }
) {
TileIcon(
icon = icon,
@@ -269,13 +271,29 @@
onAddTile: (TileSpec, Int) -> Unit,
onRemoveTile: (TileSpec) -> Unit,
) {
- val (currentTiles, otherTiles) = tiles.partition { it.isCurrent }
- val (otherTilesStock, otherTilesCustom) = otherTiles.partition { it.appName == null }
+ val currentListState = rememberEditListState(tiles)
+ val dragAndDropState = rememberDragAndDropState(currentListState)
+
+ val (currentTiles, otherTiles) = currentListState.tiles.partition { it.isCurrent }
+ val (otherTilesStock, otherTilesCustom) =
+ otherTiles
+ .filter { !dragAndDropState.isMoving(it.tileSpec) }
+ .partition { it.appName == null }
val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
onAddTile(it, CurrentTilesInteractor.POSITION_AT_END)
}
- TileLazyGrid(modifier = modifier, columns = columns) {
+ val onDropAdd: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, position ->
+ onAddTile(tileSpec, position)
+ }
+ val onDropRemove: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, _ ->
+ onRemoveTile(tileSpec)
+ }
+
+ TileLazyGrid(
+ modifier = modifier.dragAndDropTileList(dragAndDropState, { true }, onDropAdd),
+ columns = columns
+ ) {
// These Text are just placeholders to see the different sections. Not final UI.
item(span = { GridItemSpan(maxLineSpan) }) { Text("Current tiles", color = Color.White) }
@@ -285,6 +303,9 @@
onRemoveTile,
isIconOnly,
indicatePosition = true,
+ dragAndDropState = dragAndDropState,
+ acceptDrops = { true },
+ onDrop = onDropAdd,
)
item(span = { GridItemSpan(maxLineSpan) }) { Text("Tiles to add", color = Color.White) }
@@ -294,6 +315,9 @@
ClickAction.ADD,
addTileToEnd,
isIconOnly,
+ dragAndDropState = dragAndDropState,
+ acceptDrops = { true },
+ onDrop = onDropRemove,
)
item(span = { GridItemSpan(maxLineSpan) }) {
@@ -305,6 +329,9 @@
ClickAction.ADD,
addTileToEnd,
isIconOnly,
+ dragAndDropState = dragAndDropState,
+ acceptDrops = { true },
+ onDrop = onDropRemove,
)
}
}
@@ -314,6 +341,9 @@
clickAction: ClickAction,
onClick: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
+ dragAndDropState: DragAndDropState,
+ acceptDrops: (TileSpec) -> Boolean,
+ onDrop: (TileSpec, Int) -> Unit,
showLabels: Boolean = false,
indicatePosition: Boolean = false,
) {
@@ -322,41 +352,44 @@
key = { tiles[it].tileSpec.spec },
span = { GridItemSpan(if (isIconOnly(tiles[it].tileSpec)) 1 else 2) },
contentType = { TileType }
- ) {
- val viewModel = tiles[it]
- val canClick =
- when (clickAction) {
- ClickAction.ADD -> AvailableEditActions.ADD in viewModel.availableEditActions
- ClickAction.REMOVE -> AvailableEditActions.REMOVE in viewModel.availableEditActions
- }
- val onClickActionName =
- when (clickAction) {
- ClickAction.ADD ->
- stringResource(id = R.string.accessibility_qs_edit_tile_add_action)
- ClickAction.REMOVE ->
- stringResource(id = R.string.accessibility_qs_edit_remove_tile_action)
- }
- val stateDescription =
- if (indicatePosition) {
- stringResource(id = R.string.accessibility_qs_edit_position, it + 1)
- } else {
- ""
- }
-
+ ) { index ->
+ val viewModel = tiles[index]
val iconOnly = isIconOnly(viewModel.tileSpec)
val tileHeight = tileHeight(iconOnly && showLabels)
- EditTile(
- tileViewModel = viewModel,
- iconOnly = iconOnly,
- showLabels = showLabels,
- clickEnabled = canClick,
- onClick = { onClick.invoke(viewModel.tileSpec) },
- modifier =
- Modifier.height(tileHeight).animateItem().semantics {
- onClick(onClickActionName) { false }
- this.stateDescription = stateDescription
+
+ if (!dragAndDropState.isMoving(viewModel.tileSpec)) {
+ val onClickActionName =
+ when (clickAction) {
+ ClickAction.ADD ->
+ stringResource(id = R.string.accessibility_qs_edit_tile_add_action)
+ ClickAction.REMOVE ->
+ stringResource(id = R.string.accessibility_qs_edit_remove_tile_action)
}
- )
+ val stateDescription =
+ if (indicatePosition) {
+ stringResource(id = R.string.accessibility_qs_edit_position, index + 1)
+ } else {
+ ""
+ }
+ EditTile(
+ tileViewModel = viewModel,
+ iconOnly = iconOnly,
+ showLabels = showLabels,
+ modifier =
+ Modifier.height(tileHeight)
+ .animateItem()
+ .semantics {
+ onClick(onClickActionName) { false }
+ this.stateDescription = stateDescription
+ }
+ .dragAndDropTile(dragAndDropState, viewModel.tileSpec, acceptDrops, onDrop)
+ .dragAndDropTileSource(
+ viewModel.tileSpec,
+ onClick,
+ dragAndDropState,
+ )
+ )
+ }
}
}
@@ -365,8 +398,6 @@
tileViewModel: EditTileViewModel,
iconOnly: Boolean,
showLabels: Boolean,
- clickEnabled: Boolean,
- onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val label = tileViewModel.label.load() ?: tileViewModel.tileSpec.spec
@@ -377,9 +408,6 @@
showLabels = showLabels,
label = label,
iconOnly = iconOnly,
- clickEnabled = clickEnabled,
- onClick = { onClick() },
- onLongClick = { onClick() },
modifier = modifier,
) {
if (iconOnly) {
@@ -394,9 +422,6 @@
secondaryLabel = tileViewModel.appName?.load(),
icon = tileViewModel.icon,
colors = colors,
- clickEnabled = clickEnabled,
- onClick = { onClick() },
- onLongClick = { onClick() },
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
index ba9a044..a4c8638 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
@@ -26,7 +26,7 @@
* [isCurrent] indicates whether this tile is part of the current set of tiles that the user sees in
* Quick Settings.
*/
-class EditTileViewModel(
+data class EditTileViewModel(
val tileSpec: TileSpec,
val icon: Icon,
val label: Text,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
new file mode 100644
index 0000000..b3acace
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.qs.panels.domain.interactor.QuickQuickSettingsRowInteractor
+import com.android.systemui.qs.panels.shared.model.SizedTile
+import com.android.systemui.qs.panels.shared.model.TileRow
+import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.stateIn
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class QuickQuickSettingsViewModel
+@Inject
+constructor(
+ tilesInteractor: CurrentTilesInteractor,
+ fixedColumnsSizeViewModel: FixedColumnsSizeViewModel,
+ quickQuickSettingsRowInteractor: QuickQuickSettingsRowInteractor,
+ private val iconTilesViewModel: IconTilesViewModel,
+ @Application private val applicationScope: CoroutineScope,
+) {
+
+ val columns = fixedColumnsSizeViewModel.columns
+
+ private val rows =
+ quickQuickSettingsRowInteractor.rows.stateIn(
+ applicationScope,
+ SharingStarted.WhileSubscribed(),
+ quickQuickSettingsRowInteractor.defaultRows
+ )
+
+ val tileViewModels: Flow<List<SizedTile<TileViewModel>>> =
+ columns.flatMapLatest { columns ->
+ tilesInteractor.currentTiles.combine(rows, ::Pair).mapLatest { (tiles, rows) ->
+ tiles
+ .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) }
+ .let { splitInRowsSequence(it, columns).take(rows).toList().flatten() }
+ }
+ }
+
+ private val TileSpec.width: Int
+ get() = if (iconTilesViewModel.isIconTile(this)) 1 else 2
+
+ companion object {
+ private fun splitInRowsSequence(
+ tiles: List<SizedTile<TileViewModel>>,
+ columns: Int,
+ ): Sequence<List<SizedTile<TileViewModel>>> = sequence {
+ val row = TileRow<TileViewModel>(columns)
+ for (tile in tiles) {
+ check(tile.width <= columns)
+ if (!row.maybeAddTile(tile)) {
+ // Couldn't add tile to previous row, create a row with the current tiles
+ // and start a new one
+ yield(row.tiles)
+ row.clear()
+ row.maybeAddTile(tile)
+ }
+ }
+ if (row.tiles.isNotEmpty()) {
+ yield(row.tiles)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
index 4c21080..8c75cf0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
@@ -17,6 +17,7 @@
package com.android.systemui.qs.tiles.base.viewmodel
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
@@ -61,6 +62,7 @@
private val qsTileConfigProvider: QSTileConfigProvider,
private val systemClock: SystemClock,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ @UiBackground private val uiBackgroundDispatcher: CoroutineDispatcher,
private val customTileComponentBuilder: CustomTileComponent.Builder,
) : QSTileViewModelFactory<CustomTileDataModel> {
@@ -86,6 +88,7 @@
qsTileLogger,
systemClock,
backgroundDispatcher,
+ uiBackgroundDispatcher,
component.coroutineScope(),
)
}
@@ -106,6 +109,7 @@
private val qsTileConfigProvider: QSTileConfigProvider,
private val systemClock: SystemClock,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ @UiBackground private val uiBackgroundDispatcher: CoroutineDispatcher,
private val coroutineScopeFactory: QSTileCoroutineScopeFactory,
) : QSTileViewModelFactory<T> {
@@ -136,6 +140,7 @@
qsTileLogger,
systemClock,
backgroundDispatcher,
+ uiBackgroundDispatcher,
coroutineScopeFactory.create(),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
index 8782524..9e84f01 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
@@ -40,6 +40,7 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancel
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -59,7 +60,9 @@
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.transformLatest
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Provides a hassle-free way to implement new tiles according to current System UI architecture
@@ -81,6 +84,7 @@
private val qsTileLogger: QSTileLogger,
private val systemClock: SystemClock,
private val backgroundDispatcher: CoroutineDispatcher,
+ uiBackgroundDispatcher: CoroutineDispatcher,
private val tileScope: CoroutineScope,
) : QSTileViewModel, Dumpable {
@@ -93,18 +97,16 @@
private val tileData: SharedFlow<DATA_TYPE> = createTileDataFlow()
- override val state: SharedFlow<QSTileState> =
+ override val state: StateFlow<QSTileState?> =
tileData
.map { data ->
- mapper().map(config, data).also { state ->
- qsTileLogger.logStateUpdate(spec, state, data)
- }
+ withContext(uiBackgroundDispatcher) { mapper().map(config, data) }
+ .also { state -> qsTileLogger.logStateUpdate(spec, state, data) }
}
- .flowOn(backgroundDispatcher)
- .shareIn(
+ .stateIn(
tileScope,
SharingStarted.WhileSubscribed(),
- replay = 1,
+ null,
)
override val isAvailable: StateFlow<Boolean> =
users
@@ -147,26 +149,26 @@
private fun createTileDataFlow(): SharedFlow<DATA_TYPE> =
users
- .flatMapLatest { user ->
- val updateTriggers =
- merge(
- userInputFlow(user),
- forceUpdates
- .map { DataUpdateTrigger.ForceUpdate }
- .onEach { qsTileLogger.logForceUpdate(spec) },
- )
- .onStart {
- emit(DataUpdateTrigger.InitialRequest)
- qsTileLogger.logInitialRequest(spec)
- }
- .shareIn(tileScope, SharingStarted.WhileSubscribed())
- tileDataInteractor()
- .tileData(user, updateTriggers)
- // combine makes sure updateTriggers is always listened even if
- // tileDataInteractor#tileData doesn't flatMapLatest on it
- .combine(updateTriggers) { data, _ -> data }
- .cancellable()
- .flowOn(backgroundDispatcher)
+ .transformLatest { user ->
+ coroutineScope {
+ val updateTriggers: Flow<DataUpdateTrigger> =
+ merge(
+ userInputFlow(user),
+ forceUpdates
+ .map { DataUpdateTrigger.ForceUpdate }
+ .onEach { qsTileLogger.logForceUpdate(spec) },
+ )
+ .onStart { qsTileLogger.logInitialRequest(spec) }
+ .stateIn(this, SharingStarted.Eagerly, DataUpdateTrigger.InitialRequest)
+ tileDataInteractor()
+ .tileData(user, updateTriggers)
+ // combine makes sure updateTriggers is always listened even if
+ // tileDataInteractor#tileData doesn't transformLatest on it
+ .combine(updateTriggers) { data, _ -> data }
+ .cancellable()
+ .flowOn(backgroundDispatcher)
+ .collect { emit(it) }
+ }
}
.distinctUntilChanged()
.shareIn(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
index 1e8ce58..233e913 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
@@ -30,11 +30,9 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.stateIn
/** Observes one qr scanner state changes providing the [QRCodeScannerTileModel]. */
class QRCodeScannerTileDataInteractor
@@ -66,11 +64,6 @@
}
.onStart { emit(generateModel()) }
.flowOn(bgCoroutineContext)
- .stateIn(
- scope,
- SharingStarted.WhileSubscribed(),
- QRCodeScannerTileModel.TemporarilyUnavailable
- )
override fun availability(user: UserHandle): Flow<Boolean> =
flowOf(qrController.isCameraAvailable)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
index ae6c014..30247c4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -54,18 +54,21 @@
resources: Resources,
theme: Theme,
config: QSTileUIConfig,
- build: Builder.() -> Unit
+ builder: Builder.() -> Unit
): QSTileState {
val iconDrawable = resources.getDrawable(config.iconRes, theme)
return build(
{ Icon.Loaded(iconDrawable, null) },
resources.getString(config.labelRes),
- build,
+ builder,
)
}
- fun build(icon: () -> Icon?, label: CharSequence, build: Builder.() -> Unit): QSTileState =
- Builder(icon, label).apply(build).build()
+ fun build(
+ icon: () -> Icon?,
+ label: CharSequence,
+ builder: Builder.() -> Unit
+ ): QSTileState = Builder(icon, label).apply { builder() }.build()
}
enum class ActivationState(val legacyState: Int) {
@@ -107,7 +110,9 @@
sealed interface SideViewIcon {
data class Custom(val icon: Icon) : SideViewIcon
+
data object Chevron : SideViewIcon
+
data object None : SideViewIcon
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
index 226e2fa0..b1b0001 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
@@ -17,7 +17,6 @@
package com.android.systemui.qs.tiles.viewmodel
import android.os.UserHandle
-import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
/**
@@ -31,7 +30,7 @@
interface QSTileViewModel {
/** State of the tile to be shown by the view. */
- val state: SharedFlow<QSTileState>
+ val state: StateFlow<QSTileState?>
val config: QSTileConfig
@@ -62,9 +61,7 @@
}
/**
- * Returns the immediate state of the tile or null if the state haven't been collected yet. Favor
- * reactive consumption over the [currentState], because there is no guarantee that current value
- * would be available at any time.
+ * Returns the immediate state of the tile or null if the state haven't been collected yet.
*/
val QSTileViewModel.currentState: QSTileState?
- get() = state.replayCache.lastOrNull()
+ get() = state.value
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index 7be13e0..ba0a8d6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -38,6 +38,7 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectIndexed
+import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
@@ -168,6 +169,7 @@
if (listeningClients.size == 1) {
stateJob =
qsTileViewModel.state
+ .filterNotNull()
.map { mapState(context, it, qsTileViewModel.config) }
.onEach { legacyState ->
synchronized(callbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
index 64f1fd3..00b7e61 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
@@ -17,12 +17,11 @@
package com.android.systemui.qs.tiles.viewmodel
import android.os.UserHandle
-import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
object StubQSTileViewModel : QSTileViewModel {
- override val state: SharedFlow<QSTileState>
+ override val state: StateFlow<QSTileState?>
get() = error("Don't call stubs")
override val config: QSTileConfig
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
index a04fa38..6ccd169 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
@@ -19,6 +19,7 @@
import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
import javax.inject.Inject
@@ -29,4 +30,5 @@
val brightnessSliderViewModel: BrightnessSliderViewModel,
val tileGridViewModel: TileGridViewModel,
val editModeViewModel: EditModeViewModel,
+ val quickQuickSettingsViewModel: QuickQuickSettingsViewModel,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
index e395d30..66fcbac 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
@@ -20,42 +20,54 @@
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
-import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeAlignment
import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel
import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
/** Models UI state and handles user input for the Quick Settings Shade scene. */
@SysUISingleton
class QuickSettingsShadeSceneViewModel
@Inject
constructor(
- shadeInteractor: ShadeInteractor,
+ private val shadeInteractor: ShadeInteractor,
val overlayShadeViewModel: OverlayShadeViewModel,
- val brightnessSliderViewModel: BrightnessSliderViewModel,
- val tileGridViewModel: TileGridViewModel,
- val editModeViewModel: EditModeViewModel,
- val qsSceneAdapter: QSSceneAdapter,
+ val quickSettingsContainerViewModel: QuickSettingsContainerViewModel,
+ @Application applicationScope: CoroutineScope,
) {
+
+ val isEditing: StateFlow<Boolean> = quickSettingsContainerViewModel.editModeViewModel.isEditing
+
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
- MutableStateFlow(
- mapOf(
- if (shadeInteractor.shadeAlignment == ShadeAlignment.Top) {
- Swipe.Up
- } else {
- Swipe.Down
- } to SceneFamilies.Home,
- Back to SceneFamilies.Home,
- )
+ isEditing
+ .map { editing -> destinations(editing) }
+ .stateIn(
+ applicationScope,
+ SharingStarted.WhileSubscribed(),
+ destinations(isEditing.value)
)
- .asStateFlow()
+
+ private fun destinations(editing: Boolean): Map<UserAction, UserActionResult> {
+ return buildMap {
+ put(
+ if (shadeInteractor.shadeAlignment == ShadeAlignment.Top) {
+ Swipe.Up
+ } else {
+ Swipe.Down
+ },
+ UserActionResult(SceneFamilies.Home)
+ )
+ if (!editing) {
+ put(Back, UserActionResult(SceneFamilies.Home))
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 23faf7d..e07b057 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -62,6 +62,7 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
@@ -90,11 +91,11 @@
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationBar;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
@@ -177,7 +178,7 @@
private boolean mBound;
private boolean mIsEnabled;
- private boolean mIsNonPrimaryUser;
+ private boolean mIsSystemOrVisibleBgUser;
private int mCurrentBoundedUserId = -1;
private boolean mInputFocusTransferStarted;
private float mInputFocusTransferStartY;
@@ -629,6 +630,7 @@
SysUiState sysUiState,
Provider<SceneInteractor> sceneInteractor,
UserTracker userTracker,
+ UserManager userManager,
WakefulnessLifecycle wakefulnessLifecycle,
UiEventLogger uiEventLogger,
DisplayTracker displayTracker,
@@ -639,10 +641,18 @@
Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder,
BroadcastDispatcher broadcastDispatcher
) {
- // b/241601880: This component shouldn't be running for a non-primary user
- mIsNonPrimaryUser = !Process.myUserHandle().equals(UserHandle.SYSTEM);
- if (mIsNonPrimaryUser) {
- Log.wtf(TAG_OPS, "Unexpected initialization for non-primary user", new Throwable());
+ // b/241601880: This component should only be running for primary users or
+ // secondaryUsers when visibleBackgroundUsers are supported.
+ boolean isSystemUser = Process.myUserHandle().equals(UserHandle.SYSTEM);
+ boolean isVisibleBackgroundUser =
+ userManager.isVisibleBackgroundUsersSupported() && !userManager.isUserForeground();
+ if (!isSystemUser && isVisibleBackgroundUser) {
+ Log.d(TAG_OPS, "Initialization for visibleBackgroundUser");
+ }
+ mIsSystemOrVisibleBgUser = isSystemUser || isVisibleBackgroundUser;
+ if (!mIsSystemOrVisibleBgUser) {
+ Log.wtf(TAG_OPS, "Unexpected initialization for non-system foreground user",
+ new Throwable());
}
mContext = context;
@@ -833,11 +843,12 @@
}
private void internalConnectToCurrentUser(String reason) {
- if (mIsNonPrimaryUser) {
+ if (!mIsSystemOrVisibleBgUser) {
// This should not happen, but if any per-user SysUI component has a dependency on OPS,
// then this could get triggered
- Log.w(TAG_OPS, "Skipping connection to overview service due to non-primary user "
- + "caller");
+ Log.w(TAG_OPS,
+ "Skipping connection to overview service due to non-system foreground user "
+ + "caller");
return;
}
disconnectFromLauncherService(reason);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 2b717cb..8d0a386 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -57,8 +57,8 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.QuickStepContract;
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
index 6bcd923..233e9b5 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
@@ -121,7 +121,7 @@
private val SceneKey.canBeOccluded: Boolean
get() =
when (this) {
- Scenes.Bouncer -> true
+ Scenes.Bouncer -> false
Scenes.Communal -> true
Scenes.Gone -> true
Scenes.Lockscreen -> true
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index 25a9e9e..ef01194 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -167,6 +167,10 @@
initialValue = isVisibleInternal()
)
+ /** Whether there's an ongoing remotely-initiated user interaction. */
+ val isRemoteUserInteractionOngoing: StateFlow<Boolean> =
+ repository.isRemoteUserInteractionOngoing
+
/**
* The amount of transition into or out of the given [scene].
*
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index fbc0748..1f4820a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -38,8 +38,10 @@
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
+import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor
import com.android.systemui.model.SceneContainerPlugin
import com.android.systemui.model.SysUiState
@@ -106,6 +108,7 @@
private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
private val bouncerInteractor: BouncerInteractor,
private val keyguardInteractor: KeyguardInteractor,
+ private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val sysUiState: SysUiState,
@DisplayId private val displayId: Int,
private val sceneLogger: SceneLogger,
@@ -126,6 +129,7 @@
private val shadeSessionStorage: SessionStorage,
private val windowMgrLockscreenVisInteractor: WindowManagerLockscreenVisibilityInteractor,
private val keyguardEnabledInteractor: KeyguardEnabledInteractor,
+ private val dismissCallbackRegistry: DismissCallbackRegistry,
) : CoreStartable {
private val centralSurfaces: CentralSurfaces?
get() = centralSurfacesOptLazy.get().getOrNull()
@@ -144,6 +148,7 @@
hydrateBackStack()
resetShadeSessions()
handleKeyguardEnabledness()
+ notifyKeyguardDismissCallbacks()
} else {
sceneLogger.logFrameworkEnabled(
isEnabled = false,
@@ -417,9 +422,9 @@
powerInteractor.isAsleep.collect { isAsleep ->
if (isAsleep) {
switchToScene(
- // TODO(b/336581871): add sceneState?
targetSceneKey = Scenes.Lockscreen,
loggingReason = "device is starting to sleep",
+ sceneState = keyguardTransitionInteractor.asleepKeyguardState.value,
)
} else {
val canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value
@@ -699,10 +704,15 @@
}
}
- private fun switchToScene(targetSceneKey: SceneKey, loggingReason: String) {
+ private fun switchToScene(
+ targetSceneKey: SceneKey,
+ loggingReason: String,
+ sceneState: Any? = null
+ ) {
sceneInteractor.changeScene(
toScene = targetSceneKey,
loggingReason = loggingReason,
+ sceneState = sceneState,
)
}
@@ -713,4 +723,16 @@
}
}
}
+
+ private fun notifyKeyguardDismissCallbacks() {
+ applicationScope.launch {
+ sceneInteractor.currentScene.pairwise().collect { (from, to) ->
+ when {
+ from != Scenes.Bouncer -> Unit
+ to == Scenes.Gone -> dismissCallbackRegistry.notifyDismissSucceeded()
+ else -> dismissCallbackRegistry.notifyDismissCancelled()
+ }
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index d380251..a28222e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -26,17 +26,12 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
/** Models UI state for the scene container. */
@SysUISingleton
@@ -46,7 +41,6 @@
private val sceneInteractor: SceneInteractor,
private val falsingInteractor: FalsingInteractor,
private val powerInteractor: PowerInteractor,
- scenes: Set<@JvmSuppressWildcards Scene>,
) {
/**
* Keys of all scenes in the container.
@@ -62,25 +56,6 @@
/** Whether the container is visible. */
val isVisible: StateFlow<Boolean> = sceneInteractor.isVisible
- private val destinationScenesBySceneKey =
- scenes.associate { scene ->
- scene.key to scene.destinationScenes.flatMapLatestConflated { replaceSceneFamilies(it) }
- }
-
- fun currentDestinationScenes(
- scope: CoroutineScope,
- ): StateFlow<Map<UserAction, UserActionResult>> {
- return currentScene
- .flatMapLatestConflated { currentSceneKey ->
- checkNotNull(destinationScenesBySceneKey[currentSceneKey])
- }
- .stateIn(
- scope = scope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = emptyMap(),
- )
- }
-
/**
* Binds the given flow so the system remembers it.
*
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
index 59b47dc..c4f6cd9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
@@ -23,6 +23,7 @@
import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.ACTION_FINISH_FROM_TRAMPOLINE;
import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CALLING_PACKAGE_NAME;
import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CALLING_PACKAGE_TASK_ID;
+import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CLIP_DATA;
import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_RESULT_RECEIVER;
import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI;
import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.PERMISSION_SELF;
@@ -46,11 +47,15 @@
import android.util.Log;
import android.view.View;
import android.widget.Button;
+import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.activity.ComponentActivity;
import androidx.annotation.Nullable;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
import androidx.lifecycle.ViewModelProvider;
import com.android.internal.logging.UiEventLogger;
@@ -100,7 +105,8 @@
private CropView mCropView;
private Button mSave;
private Button mCancel;
- private TextView mBacklinksData;
+ private CheckBox mBacklinksIncludeDataCheckBox;
+ private TextView mBacklinksDataTextView;
private AppClipsViewModel mViewModel;
private ResultReceiver mResultReceiver;
@@ -156,18 +162,30 @@
mLayout = getLayoutInflater().inflate(R.layout.app_clips_screenshot, null);
mRoot = mLayout.findViewById(R.id.root);
+ // Manually handle window insets post Android V to support edge-to-edge display.
+ ViewCompat.setOnApplyWindowInsetsListener(mRoot, (v, windowInsets) -> {
+ Insets insets = windowInsets.getInsets(
+ WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
+ v.setPadding(insets.left, insets.top, insets.right, insets.bottom);
+ return WindowInsetsCompat.CONSUMED;
+ });
+
mSave = mLayout.findViewById(R.id.save);
mCancel = mLayout.findViewById(R.id.cancel);
mSave.setOnClickListener(this::onClick);
mCancel.setOnClickListener(this::onClick);
mCropView = mLayout.findViewById(R.id.crop_view);
- mBacklinksData = mLayout.findViewById(R.id.backlinks_data);
mPreview = mLayout.findViewById(R.id.preview);
-
mPreview.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
updateImageDimensions());
+ mBacklinksDataTextView = mLayout.findViewById(R.id.backlinks_data);
+ mBacklinksIncludeDataCheckBox = mLayout.findViewById(R.id.backlinks_include_data);
+ mBacklinksIncludeDataCheckBox.setOnCheckedChangeListener(
+ (buttonView, isChecked) ->
+ mBacklinksDataTextView.setVisibility(isChecked ? View.VISIBLE : View.GONE));
+
mViewModel = new ViewModelProvider(this, mViewModelFactory).get(AppClipsViewModel.class);
mViewModel.getScreenshot().observe(this, this::setScreenshot);
mViewModel.getResultLiveData().observe(this, this::setResultThenFinish);
@@ -233,6 +251,9 @@
// Screenshot is now available so set content view.
setContentView(mLayout);
+
+ // Request view to apply insets as it is added late and not when activity was first created.
+ mRoot.requestApplyInsets();
}
private void onClick(View view) {
@@ -280,11 +301,19 @@
data.putInt(Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE,
Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
data.putParcelable(EXTRA_SCREENSHOT_URI, uri);
+
+ if (mBacklinksIncludeDataCheckBox.getVisibility() == View.VISIBLE
+ && mBacklinksIncludeDataCheckBox.isChecked()
+ && mViewModel.getBacklinksLiveData().getValue() != null) {
+ ClipData backlinksData = mViewModel.getBacklinksLiveData().getValue().getClipData();
+ data.putParcelable(EXTRA_CLIP_DATA, backlinksData);
+ }
+
try {
mResultReceiver.send(Activity.RESULT_OK, data);
logUiEvent(SCREENSHOT_FOR_NOTE_ACCEPTED);
} catch (Exception e) {
- // Do nothing.
+ Log.e(TAG, "Error while returning data to trampoline activity", e);
}
// Nullify the ResultReceiver before finishing to avoid resending the result.
@@ -297,13 +326,18 @@
finish();
}
- private void setBacklinksData(ClipData clipData) {
- if (mBacklinksData.getVisibility() == View.GONE) {
- mBacklinksData.setVisibility(View.VISIBLE);
- }
+ private void setBacklinksData(InternalBacklinksData backlinksData) {
+ mBacklinksIncludeDataCheckBox.setVisibility(View.VISIBLE);
+ mBacklinksDataTextView.setVisibility(
+ mBacklinksIncludeDataCheckBox.isChecked() ? View.VISIBLE : View.GONE);
- mBacklinksData.setText(String.format(getString(R.string.backlinks_string),
- clipData.getDescription().getLabel()));
+ mBacklinksDataTextView.setText(backlinksData.getClipData().getDescription().getLabel());
+
+ Drawable appIcon = backlinksData.getAppIcon();
+ int size = getResources().getDimensionPixelSize(R.dimen.appclips_backlinks_icon_size);
+ appIcon.setBounds(/* left= */ 0, /* top= */ 0, /* right= */ size, /* bottom= */ size);
+ mBacklinksDataTextView.setCompoundDrawablesRelative(/* start= */ appIcon, /* top= */
+ null, /* end= */ null, /* bottom= */ null);
}
private void setError(int errorCode) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
index 3c4469d..0161f78 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
@@ -26,6 +26,7 @@
import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.ClipData;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -82,6 +83,7 @@
private static final String TAG = AppClipsTrampolineActivity.class.getSimpleName();
static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
static final String EXTRA_SCREENSHOT_URI = TAG + "SCREENSHOT_URI";
+ static final String EXTRA_CLIP_DATA = TAG + "CLIP_DATA";
static final String ACTION_FINISH_FROM_TRAMPOLINE = TAG + "FINISH_FROM_TRAMPOLINE";
static final String EXTRA_RESULT_RECEIVER = TAG + "RESULT_RECEIVER";
static final String EXTRA_CALLING_PACKAGE_NAME = TAG + "CALLING_PACKAGE_NAME";
@@ -265,6 +267,11 @@
convertedData.setData(uri);
}
+ if (resultData.containsKey(EXTRA_CLIP_DATA)) {
+ ClipData backlinksData = resultData.getParcelable(EXTRA_CLIP_DATA, ClipData.class);
+ convertedData.setClipData(backlinksData);
+ }
+
// Broadcast no longer required, setting it to null.
mKillAppClipsBroadcastIntent = null;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
index 9bb7bbf..d30d518 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
@@ -92,7 +92,7 @@
private final MutableLiveData<Bitmap> mScreenshotLiveData;
private final MutableLiveData<Uri> mResultLiveData;
private final MutableLiveData<Integer> mErrorLiveData;
- private final MutableLiveData<ClipData> mBacklinksLiveData;
+ private final MutableLiveData<InternalBacklinksData> mBacklinksLiveData;
private AppClipsViewModel(AppClipsCrossProcessHelper appClipsCrossProcessHelper,
ImageExporter imageExporter, IActivityTaskManager atmService,
@@ -144,10 +144,11 @@
*/
void triggerBacklinks(Set<Integer> taskIdsToIgnore, int displayId) {
mBgExecutor.execute(() -> {
- ListenableFuture<ClipData> backlinksData = getBacklinksData(taskIdsToIgnore, displayId);
+ ListenableFuture<InternalBacklinksData> backlinksData = getBacklinksData(
+ taskIdsToIgnore, displayId);
Futures.addCallback(backlinksData, new FutureCallback<>() {
@Override
- public void onSuccess(@Nullable ClipData result) {
+ public void onSuccess(@Nullable InternalBacklinksData result) {
if (result != null) {
mBacklinksLiveData.setValue(result);
}
@@ -180,8 +181,8 @@
return mErrorLiveData;
}
- /** Returns a {@link LiveData} that holds the Backlinks data in {@link ClipData}. */
- LiveData<ClipData> getBacklinksLiveData() {
+ /** Returns a {@link LiveData} that holds Backlinks data in {@link InternalBacklinksData}. */
+ LiveData<InternalBacklinksData> getBacklinksLiveData() {
return mBacklinksLiveData;
}
@@ -226,7 +227,7 @@
return HardwareRenderer.createHardwareBitmap(output, bounds.width(), bounds.height());
}
- private ListenableFuture<ClipData> getBacklinksData(Set<Integer> taskIdsToIgnore,
+ private ListenableFuture<InternalBacklinksData> getBacklinksData(Set<Integer> taskIdsToIgnore,
int displayId) {
return getAllRootTaskInfosOnDisplay(displayId)
.stream()
@@ -264,8 +265,9 @@
!= null;
}
- private ListenableFuture<ClipData> getBacklinksDataForTaskId(RootTaskInfo taskInfo) {
- SettableFuture<ClipData> backlinksData = SettableFuture.create();
+ private ListenableFuture<InternalBacklinksData> getBacklinksDataForTaskId(
+ RootTaskInfo taskInfo) {
+ SettableFuture<InternalBacklinksData> backlinksData = SettableFuture.create();
int taskId = taskInfo.taskId;
mAssistContentRequester.requestAssistContent(taskId, assistContent ->
backlinksData.set(getBacklinksDataFromAssistContent(taskInfo, assistContent)));
@@ -273,7 +275,7 @@
}
/**
- * A utility method to get {@link ClipData} to use for Backlinks functionality from
+ * A utility method to get {@link InternalBacklinksData} to use for Backlinks functionality from
* {@link AssistContent} received from the app whose screenshot is taken.
*
* <p>There are multiple ways an app can provide deep-linkable data via {@link AssistContent}
@@ -289,14 +291,16 @@
*
* @param taskInfo {@link RootTaskInfo} of the task which provided the {@link AssistContent}.
* @param content the {@link AssistContent} to map into Backlinks {@link ClipData}.
- * @return {@link ClipData} that represents the Backlinks data.
+ * @return {@link InternalBacklinksData} that represents the Backlinks data along with app icon.
*/
- private ClipData getBacklinksDataFromAssistContent(RootTaskInfo taskInfo,
+ private InternalBacklinksData getBacklinksDataFromAssistContent(RootTaskInfo taskInfo,
@Nullable AssistContent content) {
String appName = getAppNameOfTask(taskInfo);
String packageName = taskInfo.topActivity.getPackageName();
- ClipData fallback = ClipData.newIntent(appName,
+ Drawable appIcon = taskInfo.topActivityInfo.loadIcon(mPackageManager);
+ ClipData mainLauncherIntent = ClipData.newIntent(appName,
getMainLauncherIntentForPackage(packageName));
+ InternalBacklinksData fallback = new InternalBacklinksData(mainLauncherIntent, appIcon);
if (content == null) {
return fallback;
}
@@ -306,7 +310,7 @@
Uri uri = content.getWebUri();
Intent backlinksIntent = new Intent(ACTION_VIEW).setData(uri);
if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
- return ClipData.newRawUri(appName, uri);
+ return new InternalBacklinksData(ClipData.newRawUri(appName, uri), appIcon);
}
}
@@ -314,7 +318,8 @@
if (content.isAppProvidedIntent()) {
Intent backlinksIntent = content.getIntent();
if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
- return ClipData.newIntent(appName, backlinksIntent);
+ return new InternalBacklinksData(ClipData.newIntent(appName, backlinksIntent),
+ appIcon);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/InternalBacklinksData.kt b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/InternalBacklinksData.kt
new file mode 100644
index 0000000..0e312f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/InternalBacklinksData.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot.appclips
+
+import android.content.ClipData
+import android.graphics.drawable.Drawable
+
+/** A class to hold the [ClipData] for backlinks and the corresponding app's [Drawable] icon. */
+internal data class InternalBacklinksData(val clipData: ClipData, val appIcon: Drawable)
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt
index 468a873..cebc59b 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt
@@ -21,6 +21,7 @@
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
+import androidx.core.view.setPadding
import com.android.systemui.res.R
import com.android.systemui.settings.brightness.BrightnessSliderController
@@ -33,7 +34,15 @@
val frame =
(LayoutInflater.from(context).inflate(R.layout.brightness_mirror_container, null)
as ViewGroup)
- .apply { isVisible = true }
+ .apply {
+ isVisible = true
+ // Match BrightnessMirrorController padding
+ setPadding(
+ context.resources.getDimensionPixelSize(
+ R.dimen.rounded_slider_background_padding
+ )
+ )
+ }
val sliderController = sliderControllerFactory.create(context, frame)
sliderController.init()
frame.addView(
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt
index 2651a994..79e8b87 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.settings.brightness.ui.viewModel
import android.content.res.Resources
+import android.util.Log
import android.view.View
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
@@ -67,25 +68,45 @@
override fun setLocationAndSize(view: View) {
view.getLocationInWindow(tempPosition)
val padding = resources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding)
- _toggleSlider?.rootView?.setPadding(padding, padding, padding, padding)
// Account for desired padding
_locationAndSize.value =
LocationAndSize(
- yOffset = tempPosition[1] - padding,
+ yOffsetFromContainer = view.findTopFromContainer() - padding,
+ yOffsetFromWindow = tempPosition[1] - padding,
width = view.measuredWidth + 2 * padding,
height = view.measuredHeight + 2 * padding,
)
}
+ private fun View.findTopFromContainer(): Int {
+ var out = 0
+ var view = this
+ while (view.id != R.id.quick_settings_container) {
+ out += view.top
+ val parent = view.parent as? View
+ if (parent == null) {
+ Log.wtf(TAG, "Couldn't find container in parents of $this")
+ break
+ }
+ view = parent
+ }
+ return out
+ }
+
// Callbacks are used for indicating reinflation when the config changes in some ways (like
// density). However, we don't need that as we recompose the view anyway
override fun addCallback(listener: MirrorController.BrightnessMirrorListener) {}
override fun removeCallback(listener: MirrorController.BrightnessMirrorListener) {}
+
+ companion object {
+ private const val TAG = "BrightnessMirrorViewModel"
+ }
}
data class LocationAndSize(
- val yOffset: Int = 0,
+ val yOffsetFromContainer: Int = 0,
+ val yOffsetFromWindow: Int = 0,
val width: Int = 0,
val height: Int = 0,
)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 59c1592..ba4c29a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -47,8 +47,6 @@
import com.android.systemui.communal.util.CommunalColors
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -150,8 +148,6 @@
/**
* True if either the primary or alternate bouncer are open, meaning the hub should not receive
* any touch input.
- *
- * Tracks [KeyguardTransitionInteractor.isFinishedInState] for [KeyguardState.isBouncerState].
*/
private var anyBouncerShowing = false
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 1d43ec2..04de2c2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -148,7 +148,7 @@
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel;
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
@@ -158,8 +158,8 @@
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingManager.FalsingTapListener;
@@ -775,7 +775,7 @@
@Main CoroutineDispatcher mainDispatcher,
KeyguardTransitionInteractor keyguardTransitionInteractor,
DumpManager dumpManager,
- KeyguardLongPressViewModel keyguardLongPressViewModel,
+ KeyguardTouchHandlingViewModel keyguardTouchHandlingViewModel,
KeyguardInteractor keyguardInteractor,
ActivityStarter activityStarter,
SharedNotificationContainerInteractor sharedNotificationContainerInteractor,
@@ -970,7 +970,7 @@
mKeyguardClockInteractor = keyguardClockInteractor;
KeyguardLongPressViewBinder.bind(
mView.requireViewById(R.id.keyguard_long_press),
- keyguardLongPressViewModel,
+ keyguardTouchHandlingViewModel,
() -> {
onEmptySpaceClick();
return Unit.INSTANCE;
@@ -1095,7 +1095,6 @@
initBottomArea();
mWakeUpCoordinator.setStackScroller(mNotificationStackScrollLayoutController);
- mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController);
mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
@Override
public void onFullyHiddenChanged(boolean isFullyHidden) {
@@ -3051,7 +3050,7 @@
if (mDeviceEntryFaceAuthInteractor.canFaceAuthRun()) {
mUpdateMonitor.requestActiveUnlock(
- ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY,
"lockScreenEmptySpaceTap");
} else {
mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index e41f99b..1c223db 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -369,7 +369,9 @@
}
mFalsingCollector.onTouchEvent(ev);
- mPulsingWakeupGestureHandler.onTouchEvent(ev);
+ if (!SceneContainerFlag.isEnabled()) {
+ mPulsingWakeupGestureHandler.onTouchEvent(ev);
+ }
if (!SceneContainerFlag.isEnabled()
&& mGlanceableHubContainerController.onTouchEvent(ev)) {
@@ -427,7 +429,11 @@
} else {
return logDownDispatch(ev, "hidden or hiding", true);
}
+ } else {
+ mShadeLogger.d("NSWVC: bouncer not showing");
}
+ } else {
+ mShadeLogger.d("NSWVC: touch not within view");
}
} else if (mIsTrackingBarGesture) {
final boolean sendToStatusBar = mStatusBarViewController.sendTouchToView(ev);
@@ -437,6 +443,9 @@
return logDownDispatch(ev, "sending bar gesture to status bar",
sendToStatusBar);
}
+ if (isDown) {
+ mShadeLogger.logNoTouchDispatch(mIsTrackingBarGesture, mExpandAnimationRunning);
+ }
return logDownDispatch(ev, "no custom touch dispatch of down event", null);
}
@@ -698,12 +707,22 @@
@Override
public void dump(PrintWriter pw, String[] args) {
+ pw.print(" mExpandingBelowNotch=");
+ pw.println(mExpandingBelowNotch);
pw.print(" mExpandAnimationRunning=");
pw.println(mExpandAnimationRunning);
- pw.print(" mTouchCancelled=");
- pw.println(mTouchCancelled);
+ pw.print(" mExternalTouchIntercepted=");
+ pw.println(mExternalTouchIntercepted);
+ pw.print(" mIsOcclusionTransitionRunning=");
+ pw.println(mIsOcclusionTransitionRunning);
+ pw.print(" mIsTrackingBarGesture=");
+ pw.println(mIsTrackingBarGesture);
+ pw.print(" mLaunchAnimationTimeout=");
+ pw.println(mLaunchAnimationTimeout);
pw.print(" mTouchActive=");
pw.println(mTouchActive);
+ pw.print(" mTouchCancelled=");
+ pw.println(mTouchCancelled);
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
index fe4832f0..062327d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
@@ -47,17 +47,19 @@
* display state, wake-ups are handled by [com.android.systemui.doze.DozeSensors].
*/
@SysUISingleton
-class PulsingGestureListener @Inject constructor(
- private val falsingManager: FalsingManager,
- private val dockManager: DockManager,
- private val powerInteractor: PowerInteractor,
- private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
- private val statusBarStateController: StatusBarStateController,
- private val shadeLogger: ShadeLogger,
- private val dozeInteractor: DozeInteractor,
- userTracker: UserTracker,
- tunerService: TunerService,
- dumpManager: DumpManager
+class PulsingGestureListener
+@Inject
+constructor(
+ private val falsingManager: FalsingManager,
+ private val dockManager: DockManager,
+ private val powerInteractor: PowerInteractor,
+ private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
+ private val statusBarStateController: StatusBarStateController,
+ private val shadeLogger: ShadeLogger,
+ private val dozeInteractor: DozeInteractor,
+ userTracker: UserTracker,
+ tunerService: TunerService,
+ dumpManager: DumpManager
) : GestureDetector.SimpleOnGestureListener(), Dumpable {
private var doubleTapEnabled = false
private var singleTapEnabled = false
@@ -66,21 +68,27 @@
val tunable = Tunable { key: String?, _: String? ->
when (key) {
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE ->
- doubleTapEnabled = ambientDisplayConfiguration.doubleTapGestureEnabled(
- userTracker.userId)
+ doubleTapEnabled =
+ ambientDisplayConfiguration.doubleTapGestureEnabled(userTracker.userId)
Settings.Secure.DOZE_TAP_SCREEN_GESTURE ->
- singleTapEnabled = ambientDisplayConfiguration.tapGestureEnabled(
- userTracker.userId)
+ singleTapEnabled =
+ ambientDisplayConfiguration.tapGestureEnabled(userTracker.userId)
}
}
- tunerService.addTunable(tunable,
- Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
- Settings.Secure.DOZE_TAP_SCREEN_GESTURE)
+ tunerService.addTunable(
+ tunable,
+ Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
+ Settings.Secure.DOZE_TAP_SCREEN_GESTURE
+ )
dumpManager.registerDumpable(this)
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
+ return onSingleTapUp(e.x, e.y)
+ }
+
+ fun onSingleTapUp(x: Float, y: Float): Boolean {
val isNotDocked = !dockManager.isDocked
shadeLogger.logSingleTapUp(statusBarStateController.isDozing, singleTapEnabled, isNotDocked)
if (statusBarStateController.isDozing && singleTapEnabled && isNotDocked) {
@@ -89,11 +97,13 @@
shadeLogger.logSingleTapUpFalsingState(proximityIsNotNear, isNotAFalseTap)
if (proximityIsNotNear && isNotAFalseTap) {
shadeLogger.d("Single tap handled, requesting centralSurfaces.wakeUpIfDozing")
- dozeInteractor.setLastTapToWakePosition(Point(e.x.toInt(), e.y.toInt()))
+ dozeInteractor.setLastTapToWakePosition(Point(x.toInt(), y.toInt()))
powerInteractor.wakeUpIfDozing("PULSING_SINGLE_TAP", PowerManager.WAKE_REASON_TAP)
}
+
return true
}
+
shadeLogger.d("onSingleTapUp event ignored")
return false
}
@@ -103,10 +113,18 @@
* motion events for a double tap.
*/
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
+ if (e.actionMasked != MotionEvent.ACTION_UP) {
+ return false
+ }
+
+ return onDoubleTapEvent()
+ }
+
+ fun onDoubleTapEvent(): Boolean {
// React to the [MotionEvent.ACTION_UP] event after double tap is detected. Falsing
// checks MUST be on the ACTION_UP event.
- if (e.actionMasked == MotionEvent.ACTION_UP &&
- statusBarStateController.isDozing &&
+ if (
+ statusBarStateController.isDozing &&
(doubleTapEnabled || singleTapEnabled) &&
!falsingManager.isProximityNear &&
!falsingManager.isFalseDoubleTap
@@ -114,6 +132,7 @@
powerInteractor.wakeUpIfDozing("PULSING_DOUBLE_TAP", PowerManager.WAKE_REASON_TAP)
return true
}
+
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
index ce321dc..5065baa 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
@@ -119,7 +119,7 @@
if (delayed) {
scope.launch {
delay(125)
- animateCollapseShadeInternal()
+ withContext(mainDispatcher) { animateCollapseShadeInternal() }
}
} else {
animateCollapseShadeInternal()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index b5b46f1..66a310c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -72,79 +72,78 @@
},
{
"QsTrackingNotStarted: downTime=$str1,initTouchY=$int1,y=$int2,h=$long1," +
- "slop=$double1,qsExpanded=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3"
+ "slop=$double1,qsExpanded=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3"
}
)
}
fun logMotionEvent(event: MotionEvent, message: String) {
buffer.log(
- TAG,
- LogLevel.VERBOSE,
- {
- str1 = message
- long1 = event.eventTime
- long2 = event.downTime
- int1 = event.action
- int2 = event.classification
- },
- {
- "$str1: eventTime=$long1,downTime=$long2,action=$int1,class=$int2"
- }
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ str1 = message
+ long1 = event.eventTime
+ long2 = event.downTime
+ int1 = event.action
+ int2 = event.classification
+ },
+ { "$str1: eventTime=$long1,downTime=$long2,action=$int1,class=$int2" }
)
}
/** Logs motion event dispatch results from NotificationShadeWindowViewController. */
fun logShadeWindowDispatch(event: MotionEvent, message: String, result: Boolean?) {
buffer.log(
- TAG,
- LogLevel.VERBOSE,
- {
- str1 = message
- long1 = event.eventTime
- long2 = event.downTime
- },
- {
- val prefix = when (result) {
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ str1 = message
+ long1 = event.eventTime
+ long2 = event.downTime
+ },
+ {
+ val prefix =
+ when (result) {
true -> "SHADE TOUCH REROUTED"
false -> "SHADE TOUCH BLOCKED"
null -> "SHADE TOUCH DISPATCHED"
}
- "$prefix: eventTime=$long1,downTime=$long2, reason=$str1"
- }
+ "$prefix: eventTime=$long1,downTime=$long2, reason=$str1"
+ }
)
}
fun logMotionEventStatusBarState(event: MotionEvent, statusBarState: Int, message: String) {
buffer.log(
- TAG,
- LogLevel.VERBOSE,
- {
- str1 = message
- long1 = event.eventTime
- long2 = event.downTime
- int1 = event.action
- int2 = statusBarState
- double1 = event.y.toDouble()
- },
- {
- "$str1\neventTime=$long1,downTime=$long2,y=$double1,action=$int1," +
- "statusBarState=${when (int2) {
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ str1 = message
+ long1 = event.eventTime
+ long2 = event.downTime
+ int1 = event.action
+ int2 = statusBarState
+ double1 = event.y.toDouble()
+ },
+ {
+ "$str1\neventTime=$long1,downTime=$long2,y=$double1,action=$int1," +
+ "statusBarState=${when (int2) {
0 -> "SHADE"
1 -> "KEYGUARD"
2 -> "SHADE_LOCKED"
else -> "UNKNOWN:$int2"
}}"
- }
+ }
)
}
fun logExpansionChanged(
- message: String,
- fraction: Float,
- expanded: Boolean,
- tracking: Boolean,
- dragDownPxAmount: Float,
+ message: String,
+ fraction: Float,
+ expanded: Boolean,
+ tracking: Boolean,
+ dragDownPxAmount: Float,
) {
buffer.log(
TAG,
@@ -158,7 +157,8 @@
},
{
"$str1 fraction=$double1,expanded=$bool1," +
- "tracking=$bool2," + "dragDownPxAmount=$dragDownPxAmount"
+ "tracking=$bool2," +
+ "dragDownPxAmount=$dragDownPxAmount"
}
)
}
@@ -176,24 +176,17 @@
}
fun logQsExpandImmediateChanged(newValue: Boolean) {
- buffer.log(
- TAG,
- LogLevel.VERBOSE,
- {
- bool1 = newValue
- },
- { "qsExpandImmediate=$bool1" }
- )
+ buffer.log(TAG, LogLevel.VERBOSE, { bool1 = newValue }, { "qsExpandImmediate=$bool1" })
}
fun logQsExpansionChanged(
- message: String,
- qsExpanded: Boolean,
- qsMinExpansionHeight: Int,
- qsMaxExpansionHeight: Int,
- stackScrollerOverscrolling: Boolean,
- qsAnimatorExpand: Boolean,
- animatingQs: Boolean
+ message: String,
+ qsExpanded: Boolean,
+ qsMinExpansionHeight: Int,
+ qsMaxExpansionHeight: Int,
+ stackScrollerOverscrolling: Boolean,
+ qsAnimatorExpand: Boolean,
+ animatingQs: Boolean
) {
buffer.log(
TAG,
@@ -227,8 +220,10 @@
},
{
"PulsingGestureListener#onSingleTapUp all of this must true for single " +
- "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2, isNotDocked: $bool3"
- })
+ "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2," +
+ " isNotDocked: $bool3"
+ }
+ )
}
fun logSingleTapUpFalsingState(proximityIsNotNear: Boolean, isNotFalseTap: Boolean) {
@@ -247,9 +242,9 @@
}
fun logNotInterceptingTouchInstantExpanding(
- instantExpanding: Boolean,
- notificationsDragEnabled: Boolean,
- touchDisabled: Boolean
+ instantExpanding: Boolean,
+ notificationsDragEnabled: Boolean,
+ touchDisabled: Boolean
) {
buffer.log(
TAG,
@@ -276,12 +271,12 @@
}
fun logFlingExpands(
- vel: Float,
- vectorVel: Float,
- interactionType: Int,
- minVelocityPxPerSecond: Float,
- expansionOverHalf: Boolean,
- allowExpandForSmallExpansion: Boolean
+ vel: Float,
+ vectorVel: Float,
+ interactionType: Int,
+ minVelocityPxPerSecond: Float,
+ expansionOverHalf: Boolean,
+ allowExpandForSmallExpansion: Boolean
) {
buffer.log(
TAG,
@@ -294,9 +289,11 @@
bool1 = expansionOverHalf
bool2 = allowExpandForSmallExpansion
},
- { "NPVC flingExpands called with vel: $long1, vectorVel: $long2, " +
+ {
+ "NPVC flingExpands called with vel: $long1, vectorVel: $long2, " +
"interactionType: $int1, minVelocityPxPerSecond: $double1 " +
- "expansionOverHalf: $bool1, allowExpandForSmallExpansion: $bool2" }
+ "expansionOverHalf: $bool1, allowExpandForSmallExpansion: $bool2"
+ }
)
}
@@ -338,9 +335,7 @@
buffer.log(
TAG,
LogLevel.VERBOSE,
- {
- str1 = panelState.panelStateToString()
- },
+ { str1 = panelState.panelStateToString() },
{ "New panel State: $str1" }
)
}
@@ -357,12 +352,13 @@
)
}
- private fun flingTypeToString(flingType: Int) = when (flingType) {
- FLING_EXPAND -> "FLING_EXPAND"
- FLING_COLLAPSE -> "FLING_COLLAPSE"
- FLING_HIDE -> "FLING_HIDE"
- else -> "UNKNOWN"
- }
+ private fun flingTypeToString(flingType: Int) =
+ when (flingType) {
+ FLING_EXPAND -> "FLING_EXPAND"
+ FLING_COLLAPSE -> "FLING_COLLAPSE"
+ FLING_HIDE -> "FLING_HIDE"
+ else -> "UNKNOWN"
+ }
fun logSplitShadeChanged(splitShadeEnabled: Boolean) {
buffer.log(
@@ -392,8 +388,26 @@
},
{
"CentralSurfaces updateNotificationPanelTouchState set disabled to: $bool1\n" +
- "isGoingToSleep: $bool2, !shouldControlScreenOff: $bool3," +
- "!mDeviceInteractive: $bool4, !isPulsing: $str1"
+ "isGoingToSleep: $bool2, !shouldControlScreenOff: $bool3," +
+ "!mDeviceInteractive: $bool4, !isPulsing: $str1"
+ }
+ )
+ }
+
+ fun logNoTouchDispatch(
+ isTrackingBarGesture: Boolean,
+ isExpandAnimationRunning: Boolean,
+ ) {
+ buffer.log(
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ bool1 = isTrackingBarGesture
+ bool2 = isExpandAnimationRunning
+ },
+ {
+ "NSWVC: touch not dispatched: isTrackingBarGesture: $bool1, " +
+ "isExpandAnimationRunning: $bool2"
}
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt
index d5953ca..e525b86 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt
@@ -19,6 +19,7 @@
import com.android.keyguard.LockIconViewController
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
@@ -96,7 +97,7 @@
}
override fun showAodUi() {
- sceneInteractor.changeScene(Scenes.Lockscreen, "showAodUi")
+ sceneInteractor.changeScene(Scenes.Lockscreen, "showAodUi", sceneState = KeyguardState.AOD)
// TODO(b/330311871) implement transition to AOD
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
index 3f4bcba..354d379 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
@@ -32,6 +32,8 @@
import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shade.transition.ScrimShadeTransitionController
+import com.android.systemui.statusbar.PulseExpansionHandler
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.policy.SplitShadeStateController
import javax.inject.Inject
import javax.inject.Provider
@@ -56,6 +58,8 @@
private val sceneInteractorProvider: Provider<SceneInteractor>,
private val panelExpansionInteractorProvider: Provider<PanelExpansionInteractor>,
private val shadeExpansionStateManager: ShadeExpansionStateManager,
+ private val pulseExpansionHandler: PulseExpansionHandler,
+ private val nsslc: NotificationStackScrollLayoutController,
) : CoreStartable {
override fun start() {
@@ -63,6 +67,7 @@
hydrateShadeExpansionStateManager()
logTouchesTo(touchLog)
scrimShadeTransitionController.init()
+ pulseExpansionHandler.setUp(nsslc)
}
private fun hydrateShadeExpansionStateManager() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index b0100b9..2b2aac64 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -37,7 +37,6 @@
import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import java.util.concurrent.atomic.AtomicBoolean
@@ -60,7 +59,6 @@
@Application private val applicationScope: CoroutineScope,
val qsSceneAdapter: QSSceneAdapter,
val shadeHeaderViewModel: ShadeHeaderViewModel,
- val notifications: NotificationsPlaceholderViewModel,
val brightnessMirrorViewModel: BrightnessMirrorViewModel,
val mediaCarouselInteractor: MediaCarouselInteractor,
shadeInteractor: ShadeInteractor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 2f3fc729..c1eb8bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -1276,7 +1276,7 @@
mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
mPowerPluggedInWireless = status.isPluggedInWireless() && isChargingOrFull;
mPowerPluggedInDock = status.isPluggedInDock() && isChargingOrFull;
- mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
+ mPowerPluggedIn = isPowerPluggedIn(status, isChargingOrFull);
mPowerCharged = status.isCharged();
mChargingWattage = status.maxChargingWattage;
mChargingSpeed = status.getChargingSpeed(mContext);
@@ -1562,6 +1562,11 @@
return status.isBatteryDefender();
}
+ /** Return true if the device has power plugged in. */
+ protected boolean isPowerPluggedIn(BatteryStatus status, boolean isChargingOrFull) {
+ return status.isPluggedIn() && isChargingOrFull;
+ }
+
private boolean isCurrentUser(int userId) {
return getCurrentUser() == userId;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 79218ae..e505ef7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -53,6 +53,7 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.res.R;
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.scene.shared.model.Scenes;
@@ -114,6 +115,7 @@
private final Lazy<ShadeInteractor> mShadeInteractorLazy;
private final Lazy<DeviceUnlockedInteractor> mDeviceUnlockedInteractorLazy;
private final Lazy<SceneInteractor> mSceneInteractorLazy;
+ private final Lazy<SceneContainerOcclusionInteractor> mSceneContainerOcclusionInteractorLazy;
private final Lazy<KeyguardClockInteractor> mKeyguardClockInteractorLazy;
private int mState;
private int mLastState;
@@ -182,6 +184,7 @@
Lazy<ShadeInteractor> shadeInteractorLazy,
Lazy<DeviceUnlockedInteractor> deviceUnlockedInteractorLazy,
Lazy<SceneInteractor> sceneInteractorLazy,
+ Lazy<SceneContainerOcclusionInteractor> sceneContainerOcclusionInteractor,
Lazy<KeyguardClockInteractor> keyguardClockInteractorLazy) {
mUiEventLogger = uiEventLogger;
mInteractionJankMonitorLazy = interactionJankMonitorLazy;
@@ -190,6 +193,7 @@
mShadeInteractorLazy = shadeInteractorLazy;
mDeviceUnlockedInteractorLazy = deviceUnlockedInteractorLazy;
mSceneInteractorLazy = sceneInteractorLazy;
+ mSceneContainerOcclusionInteractorLazy = sceneContainerOcclusionInteractor;
mKeyguardClockInteractorLazy = keyguardClockInteractorLazy;
for (int i = 0; i < HISTORY_SIZE; i++) {
mHistoricalRecords[i] = new HistoricalState();
@@ -199,7 +203,9 @@
@Override
public void start() {
mJavaAdapter.alwaysCollectFlow(
- mKeyguardTransitionInteractorLazy.get().isFinishedInState(GONE),
+ mKeyguardTransitionInteractorLazy.get().isFinishedIn(
+ /* scene */ Scenes.Gone,
+ /* stateWithoutSceneContainer */ GONE),
(Boolean isFinishedInState) -> {
if (isFinishedInState) {
setLeaveOpenOnKeyguardHide(false);
@@ -214,6 +220,7 @@
combineFlows(
mDeviceUnlockedInteractorLazy.get().getDeviceUnlockStatus(),
mSceneInteractorLazy.get().getCurrentScene(),
+ mSceneContainerOcclusionInteractorLazy.get().getInvisibleDueToOcclusion(),
this::calculateStateFromSceneFramework),
this::onStatusBarStateChanged);
}
@@ -664,10 +671,11 @@
private int calculateStateFromSceneFramework(
DeviceUnlockStatus deviceUnlockStatus,
- SceneKey currentScene) {
+ SceneKey currentScene,
+ boolean isOccluded) {
SceneContainerFlag.isUnexpectedlyInLegacyMode();
- if (deviceUnlockStatus.isUnlocked()) {
+ if (deviceUnlockStatus.isUnlocked() || isOccluded) {
return StatusBarState.SHADE;
} else {
return Preconditions.checkNotNull(sStatusBarStateByLockedSceneKey.get(currentScene));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index 79f1874..ed1756a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -19,6 +19,7 @@
import android.view.View
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.animation.ActivityTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -54,23 +55,26 @@
when (state) {
is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden
is OngoingCallModel.InCall -> {
- // This mimics OngoingCallController#updateChip.
- // TODO(b/332662551): Handle `state.startTimeMs = 0` correctly (see
- // b/192379214 and
- // OngoingCallController.CallNotificationInfo.hasValidStartTime).
- val startTimeInElapsedRealtime =
- state.startTimeMs - systemClock.currentTimeMillis() +
- systemClock.elapsedRealtime()
- OngoingActivityChipModel.Shown.Timer(
- icon =
- Icon.Resource(
- com.android.internal.R.drawable.ic_phone,
- contentDescription = null,
- ),
- colors = ColorsModel.Themed,
- startTimeMs = startTimeInElapsedRealtime,
- getOnClickListener(state),
- )
+ // This block mimics OngoingCallController#updateChip.
+ if (state.startTimeMs <= 0L) {
+ // If the start time is invalid, don't show a timer and show just an
+ // icon. See b/192379214.
+ OngoingActivityChipModel.Shown.IconOnly(
+ icon = phoneIcon,
+ colors = ColorsModel.Themed,
+ getOnClickListener(state),
+ )
+ } else {
+ val startTimeInElapsedRealtime =
+ state.startTimeMs - systemClock.currentTimeMillis() +
+ systemClock.elapsedRealtime()
+ OngoingActivityChipModel.Shown.Timer(
+ icon = phoneIcon,
+ colors = ColorsModel.Themed,
+ startTimeMs = startTimeInElapsedRealtime,
+ getOnClickListener(state),
+ )
+ }
}
}
}
@@ -95,4 +99,14 @@
)
}
}
+
+ companion object {
+ private val phoneIcon =
+ Icon.Resource(
+ com.android.internal.R.drawable.ic_phone,
+ ContentDescription.Resource(
+ R.string.ongoing_phone_call_content_description,
+ ),
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
index 42e921e..73ccaab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
@@ -85,7 +85,13 @@
icon =
Icon.Resource(
CAST_TO_OTHER_DEVICE_ICON,
- ContentDescription.Resource(R.string.accessibility_casting),
+ // Note: This string is "Casting screen", which is okay right now because this
+ // chip does not currently support audio-only casting. If the chip starts
+ // supporting audio-only casting (see b/342169876), update the content
+ // description to just "Casting".
+ ContentDescription.Resource(
+ R.string.cast_to_other_device_chip_accessibility_label,
+ ),
),
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
index af6d7f2..53679f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
@@ -19,6 +19,7 @@
import android.app.ActivityManager
import androidx.annotation.DrawableRes
import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -64,8 +65,13 @@
}
is ScreenRecordChipModel.Recording -> {
OngoingActivityChipModel.Shown.Timer(
- // TODO(b/332662551): Also provide a content description.
- icon = Icon.Resource(ICON, contentDescription = null),
+ icon =
+ Icon.Resource(
+ ICON,
+ ContentDescription.Resource(
+ R.string.screenrecord_ongoing_screen_only,
+ ),
+ ),
colors = ColorsModel.Red,
startTimeMs = systemClock.elapsedRealtime(),
createDialogLaunchOnClickListener(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
index c3b1456..8aef5a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
@@ -18,6 +18,7 @@
import androidx.annotation.DrawableRes
import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -78,8 +79,11 @@
state: ProjectionChipModel.Projecting,
): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.Timer(
- // TODO(b/332662551): Use the right content description.
- icon = Icon.Resource(SHARE_TO_APP_ICON, contentDescription = null),
+ icon =
+ Icon.Resource(
+ SHARE_TO_APP_ICON,
+ ContentDescription.Resource(R.string.share_to_app_chip_accessibility_label),
+ ),
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
startTimeMs = systemClock.elapsedRealtime(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index 57f609b..e8d895c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -36,6 +36,14 @@
*/
open val onClickListener: View.OnClickListener?,
) : OngoingActivityChipModel() {
+
+ /** This chip shows only an icon and nothing else. */
+ data class IconOnly(
+ override val icon: Icon,
+ override val colors: ColorsModel,
+ override val onClickListener: View.OnClickListener?,
+ ) : Shown(icon, colors, onClickListener)
+
/** The chip shows a timer, counting up from [startTimeMs]. */
data class Timer(
override val icon: Icon,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt
index 933d0ab..b467032 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt
@@ -16,13 +16,13 @@
package com.android.systemui.statusbar.data.model
-import com.android.systemui.statusbar.phone.BarTransitions
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode
+import com.android.systemui.shared.statusbar.phone.BarTransitions
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode
/**
* The possible status bar modes.
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 af8a89d..ef4dffad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -305,26 +305,20 @@
dumpManager.registerDumpable(this)
}
- fun isEnabled(): Boolean {
- execution.assertIsMainThread()
+ val isEnabled: Boolean = plugin != null
- return plugin != null
- }
+ val isDateWeatherDecoupled: Boolean = datePlugin != null && weatherPlugin != null
- fun isDateWeatherDecoupled(): Boolean {
- execution.assertIsMainThread()
-
- return datePlugin != null && weatherPlugin != null
- }
-
- fun isWeatherEnabled(): Boolean {
- execution.assertIsMainThread()
- val showWeather = secureSettings.getIntForUser(
- LOCK_SCREEN_WEATHER_ENABLED,
- 1,
- userTracker.userId) == 1
- return showWeather
- }
+ val isWeatherEnabled: Boolean
+ get() {
+ val showWeather =
+ secureSettings.getIntForUser(
+ LOCK_SCREEN_WEATHER_ENABLED,
+ 1,
+ userTracker.userId,
+ ) == 1
+ return showWeather
+ }
private fun updateBypassEnabled() {
val bypassEnabled = bypassController.bypassEnabled
@@ -337,10 +331,10 @@
fun buildAndConnectDateView(parent: ViewGroup): View? {
execution.assertIsMainThread()
- if (!isEnabled()) {
+ if (!isEnabled) {
throw RuntimeException("Cannot build view when not enabled")
}
- if (!isDateWeatherDecoupled()) {
+ if (!isDateWeatherDecoupled) {
throw RuntimeException("Cannot build date view when not decoupled")
}
@@ -361,10 +355,10 @@
fun buildAndConnectWeatherView(parent: ViewGroup): View? {
execution.assertIsMainThread()
- if (!isEnabled()) {
+ if (!isEnabled) {
throw RuntimeException("Cannot build view when not enabled")
}
- if (!isDateWeatherDecoupled()) {
+ if (!isDateWeatherDecoupled) {
throw RuntimeException("Cannot build weather view when not decoupled")
}
@@ -385,7 +379,7 @@
fun buildAndConnectView(parent: ViewGroup): View? {
execution.assertIsMainThread()
- if (!isEnabled()) {
+ if (!isEnabled) {
throw RuntimeException("Cannot build view when not enabled")
}
@@ -577,7 +571,7 @@
}
private fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean {
- if (isDateWeatherDecoupled() && t.featureType == SmartspaceTarget.FEATURE_WEATHER) {
+ if (isDateWeatherDecoupled && t.featureType == SmartspaceTarget.FEATURE_WEATHER) {
return false
}
if (!showNotifications) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index f98f77e..aff57bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -40,6 +40,7 @@
import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
import com.android.systemui.statusbar.notification.logKey
+import com.android.systemui.statusbar.notification.shared.GroupHunAnimationFix
import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
@@ -726,6 +727,12 @@
*/
private fun isAttemptingToShowHun(entry: ListEntry) =
mHeadsUpManager.isHeadsUpEntry(entry.key) || isEntryBinding(entry)
+ || isHeadsUpAnimatingAway(entry)
+
+ private fun isHeadsUpAnimatingAway(entry: ListEntry): Boolean {
+ if (!GroupHunAnimationFix.isEnabled) return false
+ return entry.representativeEntry?.row?.isHeadsUpAnimatingAway ?: false
+ }
/**
* Whether the notification is already heads up/binding per [isAttemptingToShowHun] OR if it
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
index e9306a5..069ae93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
@@ -41,4 +41,7 @@
val activeHeadsUpRows: Flow<Set<HeadsUpRowRepository>>
fun setHeadsUpAnimatingAway(animatingAway: Boolean)
+
+ /** Snooze the currently pinned HUN. */
+ fun snooze()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index 4a6553f..cdab108 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -101,10 +101,17 @@
fun headsUpRow(key: HeadsUpRowKey): HeadsUpRowInteractor =
HeadsUpRowInteractor(key as HeadsUpRowRepository)
+
fun elementKeyFor(key: HeadsUpRowKey) = (key as HeadsUpRowRepository).elementKey
+
fun setHeadsUpAnimatingAway(animatingAway: Boolean) {
headsUpRepository.setHeadsUpAnimatingAway(animatingAway)
}
+
+ /** Snooze the currently pinned HUN. */
+ fun snooze() {
+ headsUpRepository.snooze()
+ }
}
class HeadsUpRowInteractor(repository: HeadsUpRowRepository)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
index 367aaad..5e91786 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
@@ -22,19 +22,26 @@
import android.app.Notification.CATEGORY_EVENT
import android.app.Notification.CATEGORY_REMINDER
import android.app.Notification.VISIBILITY_PRIVATE
+import android.app.NotificationManager
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_HIGH
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.database.ContentObserver
import android.hardware.display.AmbientDisplayConfiguration
+import android.os.Bundle
import android.os.Handler
import android.os.PowerManager
+import android.os.SystemProperties
import android.provider.Settings
import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED
import android.provider.Settings.Global.HEADS_UP_OFF
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.settings.UserTracker
@@ -47,6 +54,7 @@
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.util.NotificationChannels
import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.settings.SystemSettings
import com.android.systemui.util.time.SystemClock
@@ -244,12 +252,22 @@
keyguardNotificationVisibilityProvider.shouldHideNotification(entry)
}
+/**
+ * Set with:
+ * adb shell setprop persist.force_show_avalanche_edu_once 1 && adb shell stop; adb shell start
+ */
+private const val FORCE_SHOW_AVALANCHE_EDU_ONCE = "persist.force_show_avalanche_edu_once"
+
+private const val PREF_HAS_SEEN_AVALANCHE_EDU = "has_seen_avalanche_edu"
+
class AvalancheSuppressor(
private val avalancheProvider: AvalancheProvider,
private val systemClock: SystemClock,
private val systemSettings: SystemSettings,
private val packageManager: PackageManager,
private val uiEventLogger: UiEventLogger,
+ private val context: Context,
+ private val notificationManager: NotificationManager
) :
VisualInterruptionFilter(
types = setOf(PEEK, PULSE),
@@ -257,6 +275,24 @@
) {
val TAG = "AvalancheSuppressor"
+ private val prefs = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE)
+
+ // SharedPreferences are persisted across reboots
+ var hasSeenEdu: Boolean
+ get() = prefs.getBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, false)
+ set(value) = prefs.edit().putBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, value).apply()
+
+ // Reset on reboot.
+ // The pipeline runs these suppressors many times very fast, so we must use a separate bool
+ // to force show for debug so that phone does not get stuck sending out infinite number of
+ // education HUNs.
+ private var hasShownOnceForDebug = false
+
+ private fun shouldShowEdu() : Boolean {
+ val forceShowOnce = SystemProperties.get(FORCE_SHOW_AVALANCHE_EDU_ONCE, "").equals("1")
+ return !hasSeenEdu || (forceShowOnce && !hasShownOnceForDebug)
+ }
+
enum class State {
ALLOW_CONVERSATION_AFTER_AVALANCHE,
ALLOW_HIGH_PRIORITY_CONVERSATION_ANY_TIME,
@@ -309,9 +345,53 @@
if (state != State.SUPPRESS) {
return false
}
+ if (shouldShowEdu()) {
+ showEdu()
+ }
return true
}
+ /**
+ * Show avalanche education HUN from SystemUI.
+ */
+ private fun showEdu() {
+ val res = context.resources
+ val titleStr = res.getString(
+ com.android.systemui.res.R.string.adaptive_notification_edu_hun_title)
+ val textStr = res.getString(
+ com.android.systemui.res.R.string.adaptive_notification_edu_hun_text)
+ val actionStr = res.getString(
+ com.android.systemui.res.R.string.go_to_adaptive_notification_settings)
+
+ val intent = Intent(Settings.ACTION_MANAGE_ADAPTIVE_NOTIFICATIONS)
+ val pendingIntent = PendingIntent.getActivity(
+ context, 0, intent,
+ PendingIntent.FLAG_IMMUTABLE
+ )
+
+ // Replace "System UI" app name with "Android System"
+ val bundle = Bundle()
+ bundle.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+ context.getString(com.android.internal.R.string.android_system_label))
+
+ val builder =
+ Notification.Builder(context, NotificationChannels.ALERTS)
+ .setTicker(titleStr)
+ .setContentTitle(titleStr)
+ .setContentText(textStr)
+ .setSmallIcon(com.android.systemui.res.R.drawable.ic_settings)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setTimeoutAfter(/* one day in ms */ 24 * 60 * 60 * 1000L)
+ .setAutoCancel(true)
+ .addAction(android.R.drawable.button_onoff_indicator_off, actionStr, pendingIntent)
+ .setContentIntent(pendingIntent)
+ .addExtras(bundle)
+
+ notificationManager.notify(SystemMessage.NOTE_ADAPTIVE_NOTIFICATIONS, builder.build())
+ hasSeenEdu = true
+ hasShownOnceForDebug = true;
+ }
+
private fun calculateState(entry: NotificationEntry): State {
if (
entry.ranking.isConversation &&
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
index 84f8662..96f94ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
@@ -15,6 +15,8 @@
*/
package com.android.systemui.statusbar.notification.interruption
+import android.app.NotificationManager
+import android.content.Context
import android.content.pm.PackageManager
import android.hardware.display.AmbientDisplayConfiguration
import android.os.Handler
@@ -68,7 +70,9 @@
private val avalancheProvider: AvalancheProvider,
private val systemSettings: SystemSettings,
private val packageManager: PackageManager,
- private val bubbles: Optional<Bubbles>
+ private val bubbles: Optional<Bubbles>,
+ private val context: Context,
+ private val notificationManager: NotificationManager
) : VisualInterruptionDecisionProvider {
init {
@@ -179,7 +183,7 @@
if (NotificationAvalancheSuppression.isEnabled) {
addFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
)
avalancheProvider.register()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index f73223f..9e943ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -104,6 +104,7 @@
import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
+import com.android.systemui.statusbar.notification.shared.TransparentHeaderFix;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -1584,6 +1585,9 @@
/* headerView= */ headerView,
/* onClickListener= */ mExpandClickListener
);
+ if (TransparentHeaderFix.isEnabled()) {
+ updateBackgroundForGroupState();
+ }
}
/**
@@ -2869,14 +2873,16 @@
}
public boolean isExpanded(boolean allowOnKeyguard) {
- // System expanded should be ignored in heads up state
final boolean isHeadsUpState = ExpandHeadsUpOnInlineReply.isEnabled()
&& canShowHeadsUp() && isHeadsUpState();
+ // System expanded should be ignored in pinned heads up state
+ final boolean isPinned = isHeadsUpState && isPinned();
// Heads Up Notification can be expanded when it is pinned.
final boolean isPinnedAndExpanded =
isHeadsUpState && isPinnedAndExpanded();
+
return (!shouldShowPublic()) && (!mOnKeyguard || allowOnKeyguard)
- && (!hasUserChangedExpansion() && !isHeadsUpState
+ && (!hasUserChangedExpansion() && !isPinned
&& (isSystemExpanded() || isSystemChildExpanded())
|| isUserExpanded() || isPinnedAndExpanded);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 96b1cf2..646d0b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1477,7 +1477,7 @@
}
if (hasRemoteInput) {
result.mView.setWrapper(wrapper);
- result.mView.addOnVisibilityChangedListener(this::setRemoteInputVisible);
+ result.mView.setOnVisibilityChangedListener(this::setRemoteInputVisible);
if (existingPendingIntent != null || result.mView.isActive()) {
// The current action could be gone, or the pending intent no longer valid.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt
new file mode 100644
index 0000000..5867612
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for com.android.systemui.Flags.FLAG_NOTIFICATION_GROUP_HUN_REMOVAL_ANIMATION_FIX */
+@Suppress("NOTHING_TO_INLINE")
+object GroupHunAnimationFix {
+ const val FLAG_NAME = Flags.FLAG_NOTIFICATION_GROUP_HUN_REMOVAL_ANIMATION_FIX
+
+ /** A token used for dependency declaration */
+ val token: FlagToken
+ get() = FlagToken(FLAG_NAME, isEnabled)
+
+ /** Are sections sorted by time? */
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.notificationGroupHunRemovalAnimationFix()
+
+ /**
+ * Called to ensure code is only run when the flag is enabled. This protects users from the
+ * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+ * build to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+ /**
+ * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+ * the flag is enabled to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt
new file mode 100644
index 0000000..0b01510
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the notification transparent header fix flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object TransparentHeaderFix {
+ /** The aconfig flag name */
+ const val FLAG_NAME = Flags.FLAG_NOTIFICATION_TRANSPARENT_HEADER_FIX
+
+ /** A token used for dependency declaration */
+ val token: FlagToken
+ get() = FlagToken(FLAG_NAME, isEnabled)
+
+ /** Is the flag enabled */
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.notificationTransparentHeaderFix()
+
+ /**
+ * Called to ensure code is only run when the flag is enabled. This protects users from the
+ * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+ * build to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+ /**
+ * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+ * the flag is enabled to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index ddfa86d..cb03334 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -1500,6 +1500,7 @@
* needed.
*/
void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
+ SceneContainerFlag.assertInLegacyMode();
mOnStackYChanged = onStackYChanged;
}
@@ -2270,6 +2271,7 @@
public void setOverscrollTopChangedListener(
OnOverscrollTopChangedListener overscrollTopChangedListener) {
+ SceneContainerFlag.assertInLegacyMode();
mOverscrollTopChangedListener = overscrollTopChangedListener;
}
@@ -3497,6 +3499,13 @@
setIsBeingDragged(true);
}
+ // Only when scene container is enabled, mark that we are being dragged so that we start
+ // dispatching the rest of the gesture to scene container.
+ void startDraggingOnHun() {
+ SceneContainerFlag.isUnexpectedlyInLegacyMode();
+ setIsBeingDragged(true);
+ }
+
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (!isScrollingEnabled()
@@ -5705,6 +5714,7 @@
* Set a listener to when scrolling changes.
*/
public void setOnScrollListener(Consumer<Integer> listener) {
+ SceneContainerFlag.assertInLegacyMode();
mScrollListener = listener;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index bf53ee2..58b72e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -59,6 +59,7 @@
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.view.OneShotPreDrawListener;
import com.android.systemui.Dumpable;
import com.android.systemui.ExpandHelper;
@@ -126,6 +127,7 @@
import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor;
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
+import com.android.systemui.statusbar.phone.HeadsUpNotificationViewControllerEmptyImpl;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -168,6 +170,7 @@
private final NotificationVisibilityProvider mVisibilityProvider;
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
private final HeadsUpManager mHeadsUpManager;
+ private HeadsUpTouchHelper mHeadsUpTouchHelper;
private final NotificationRoundnessManager mNotificationRoundnessManager;
private final TunerService mTunerService;
private final DeviceProvisionedController mDeviceProvisionedController;
@@ -706,6 +709,7 @@
NotificationVisibilityProvider visibilityProvider,
NotificationWakeUpCoordinator wakeUpCoordinator,
HeadsUpManager headsUpManager,
+ Provider<IStatusBarService> statusBarService,
NotificationRoundnessManager notificationRoundnessManager,
TunerService tunerService,
DeviceProvisionedController deviceProvisionedController,
@@ -758,6 +762,14 @@
mVisibilityProvider = visibilityProvider;
mWakeUpCoordinator = wakeUpCoordinator;
mHeadsUpManager = headsUpManager;
+ if (SceneContainerFlag.isEnabled()) {
+ mHeadsUpTouchHelper = new HeadsUpTouchHelper(
+ mHeadsUpManager,
+ statusBarService.get(),
+ getHeadsUpCallback(),
+ new HeadsUpNotificationViewControllerEmptyImpl()
+ );
+ }
mNotificationRoundnessManager = notificationRoundnessManager;
mTunerService = tunerService;
mDeviceProvisionedController = deviceProvisionedController;
@@ -1052,6 +1064,7 @@
public void setOverscrollTopChangedListener(
OnOverscrollTopChangedListener listener) {
+ SceneContainerFlag.assertInLegacyMode();
mView.setOverscrollTopChangedListener(listener);
}
@@ -1248,6 +1261,7 @@
}
public void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
+ SceneContainerFlag.assertInLegacyMode();
mView.setOnStackYChanged(onStackYChanged);
}
@@ -1750,6 +1764,7 @@
* Set a listener to when scrolling changes.
*/
public void setOnScrollListener(Consumer<Integer> listener) {
+ SceneContainerFlag.assertInLegacyMode();
mView.setOnScrollListener(listener);
}
@@ -1997,6 +2012,13 @@
&& !mView.isExpandingNotification()) {
scrollWantsIt = mView.onInterceptTouchEventScroll(ev);
}
+ boolean hunWantsIt = false;
+ if (shouldHeadsUpHandleTouch()) {
+ hunWantsIt = mHeadsUpTouchHelper.onInterceptTouchEvent(ev);
+ if (hunWantsIt) {
+ mView.startDraggingOnHun();
+ }
+ }
boolean swipeWantsIt = false;
if (mLongPressedView == null && !mView.isBeingDragged()
&& !mView.isExpandingNotification()
@@ -2026,7 +2048,7 @@
&& ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
mJankMonitor.begin(mView, CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
}
- return swipeWantsIt || scrollWantsIt || expandWantsIt || longPressWantsIt;
+ return swipeWantsIt || scrollWantsIt || expandWantsIt || longPressWantsIt || hunWantsIt;
}
@Override
@@ -2078,6 +2100,10 @@
&& !expandingNotification && !mView.getDisallowScrollingInThisMotion()) {
scrollerWantsIt = mView.onScrollTouch(ev);
}
+ boolean hunWantsIt = false;
+ if (shouldHeadsUpHandleTouch()) {
+ hunWantsIt = mHeadsUpTouchHelper.onTouchEvent(ev);
+ }
// Check if we need to clear any snooze leavebehinds
if (guts != null && !NotificationSwipeHelper.isTouchInView(ev, guts)
@@ -2098,7 +2124,8 @@
mView.setCheckForLeaveBehind(true);
}
traceJankOnTouchEvent(ev.getActionMasked(), scrollerWantsIt);
- return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || longPressWantsIt;
+ return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || longPressWantsIt
+ || hunWantsIt;
}
private void traceJankOnTouchEvent(int action, boolean scrollerWantsIt) {
@@ -2125,6 +2152,11 @@
break;
}
}
+
+ private boolean shouldHeadsUpHandleTouch() {
+ return SceneContainerFlag.isEnabled() && mLongPressedView == null
+ && !mSwipeHelper.isSwiping();
+ }
}
private class NotifStackControllerImpl implements NotifStackController {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index ebb0d7d..57e52b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -70,10 +70,10 @@
) { shadeExpansion, shadeMode, qsExpansion, transitionState, quickSettingsScene ->
when (transitionState) {
is ObservableTransitionState.Idle -> {
- if (transitionState.currentScene == Scenes.Lockscreen) {
- 1f
- } else {
- shadeExpansion
+ when (transitionState.currentScene) {
+ Scenes.Lockscreen,
+ Scenes.QuickSettings -> 1f
+ else -> shadeExpansion
}
}
is ObservableTransitionState.Transition -> {
@@ -162,9 +162,13 @@
stackAppearanceInteractor::setCurrentGestureOverscroll
/** Whether the notification stack is scrollable or not. */
- val isScrollable: Flow<Boolean> = sceneInteractor.currentScene.map {
- sceneInteractor.isSceneInFamily(it, SceneFamilies.NotifShade) || it == Scenes.Lockscreen
- }.dumpWhileCollecting("isScrollable")
+ val isScrollable: Flow<Boolean> =
+ sceneInteractor.currentScene
+ .map {
+ sceneInteractor.isSceneInFamily(it, SceneFamilies.NotifShade) ||
+ it == Scenes.Lockscreen
+ }
+ .dumpWhileCollecting("isScrollable")
/** Whether the notification stack is displayed in doze mode. */
val isDozing: Flow<Boolean> by lazy {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index 634bd7e..eb1f778 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -20,15 +20,17 @@
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
import com.android.systemui.util.kotlin.FlowDumperImpl
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
/**
* ViewModel used by the Notification placeholders inside the scene container to update the
@@ -41,8 +43,9 @@
dumpManager: DumpManager,
private val interactor: NotificationStackAppearanceInteractor,
shadeInteractor: ShadeInteractor,
+ private val shadeSceneViewModel: ShadeSceneViewModel,
+ private val headsUpNotificationInteractor: HeadsUpNotificationInteractor,
featureFlags: FeatureFlagsClassic,
- private val keyguardInteractor: KeyguardInteractor,
) : FlowDumperImpl(dumpManager) {
/** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */
val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES)
@@ -60,11 +63,23 @@
interactor.setConstrainedAvailableSpace(height)
}
+ /** Notifies that empty space on the notification scrim has been clicked. */
+ fun onEmptySpaceClicked() {
+ shadeSceneViewModel.onContentClicked()
+ }
+
/** Sets the content alpha for the current state of the brightness mirror */
fun setAlphaForBrightnessMirror(alpha: Float) {
interactor.setAlphaForBrightnessMirror(alpha)
}
+ /** Whether or not the notification scrim should be clickable. */
+ val isClickable: StateFlow<Boolean> = shadeSceneViewModel.isClickable
+
+ /** True when a HUN is pinned or animating away. */
+ val isHeadsUpOrAnimatingAway: Flow<Boolean> =
+ headsUpNotificationInteractor.isHeadsUpOrAnimatingAway
+
/** Corner rounding of the stack */
val shadeScrimRounding: Flow<ShadeScrimRounding> =
interactor.shadeScrimRounding.dumpWhileCollecting("shadeScrimRounding")
@@ -94,6 +109,11 @@
fun setScrolledToTop(scrolledToTop: Boolean) {
interactor.setScrolledToTop(scrolledToTop)
}
+
+ /** Snooze the currently pinned HUN. */
+ fun snoozeHun() {
+ headsUpNotificationInteractor.snooze()
+ }
}
// Expansion fraction thresholds (between 0-1f) at which the corresponding value should be
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 8e58ffb..1c57346 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -287,7 +287,7 @@
/** Are we on the dream without the shade/qs? */
private val isDreamingWithoutShade: Flow<Boolean> =
combine(
- keyguardTransitionInteractor.isFinishedInState(DREAMING),
+ keyguardTransitionInteractor.isFinishedIn(DREAMING),
isAnyExpanded,
) { isDreaming, isAnyExpanded ->
isDreaming && !isAnyExpanded
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index fae0a46..97266c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -126,6 +126,7 @@
animationController: ActivityTransitionAnimator.Controller?,
fillInIntent: Intent?,
extraOptions: Bundle?,
+ customMessage: String?,
) {
activityStarterInternal.startPendingIntentDismissingKeyguard(
intent = intent,
@@ -135,6 +136,7 @@
dismissShade = dismissShade,
fillInIntent = fillInIntent,
extraOptions = extraOptions,
+ customMessage = customMessage,
)
}
@@ -319,11 +321,13 @@
intent: Intent,
onlyProvisioned: Boolean,
dismissShade: Boolean,
+ customMessage: String?,
) {
activityStarterInternal.startActivityDismissingKeyguard(
intent = intent,
onlyProvisioned = onlyProvisioned,
dismissShade = dismissShade,
+ customMessage = customMessage,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
index cff9f5e..93ce6e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
@@ -42,6 +42,7 @@
skipLockscreenChecks: Boolean = false,
fillInIntent: Intent? = null,
extraOptions: Bundle? = null,
+ customMessage: String? = null,
)
/** Starts an activity after dismissing keyguard. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
index dbb95e6..ae98e1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
@@ -42,7 +42,8 @@
showOverLockscreen: Boolean,
skipLockscreenChecks: Boolean,
fillInIntent: Intent?,
- extraOptions: Bundle?
+ extraOptions: Bundle?,
+ customMessage: String?,
) {
TODO("Not yet implemented b/308819693")
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index d75a738..a0d4ca2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -41,9 +41,10 @@
import com.android.systemui.animation.ActivityTransitionAnimator;
import com.android.systemui.animation.RemoteAnimationRunnerCompat;
import com.android.systemui.display.data.repository.DisplayMetricsRepository;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.util.Compile;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
index 3bc8e27..88d3e07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
@@ -20,7 +20,7 @@
import androidx.lifecycle.LifecycleRegistry
import com.android.keyguard.AuthKeyguardMessageArea
import com.android.systemui.animation.ActivityTransitionAnimator
-import com.android.systemui.navigationbar.NavigationBarView
+import com.android.systemui.navigationbar.views.NavigationBarView
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.qs.QSPanelController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 5c262f3..462ae7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -146,7 +146,7 @@
import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder;
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.notetask.NoteTaskController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -181,6 +181,7 @@
import com.android.systemui.shade.ShadeSurface;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.CircleReveal;
import com.android.systemui.statusbar.CommandQueue;
@@ -1328,7 +1329,9 @@
.putExtra(Intent.EXTRA_TEXT, message.toString()),
"Share rejected touch report")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
- true /* onlyProvisioned */, true /* dismissShade */);
+ true /* onlyProvisioned */,
+ true /* dismissShade */,
+ null /* customMessage */);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index c5dcb09..4ce9010 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -31,6 +31,7 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -105,6 +106,8 @@
private boolean mIsExpanded;
private int mStatusBarState;
private AnimationStateHandler mAnimationStateHandler;
+
+ private Handler mBgHandler;
private int mHeadsUpInset;
// Used for determining the region for touch interaction
@@ -149,7 +152,8 @@
UiEventLogger uiEventLogger,
JavaAdapter javaAdapter,
ShadeInteractor shadeInteractor,
- AvalancheController avalancheController) {
+ AvalancheController avalancheController,
+ @Background Handler bgHandler) {
super(context, logger, handler, globalSettings, systemClock, executor,
accessibilityManagerWrapper, uiEventLogger, avalancheController);
Resources resources = mContext.getResources();
@@ -159,7 +163,7 @@
mGroupMembershipManager = groupMembershipManager;
mVisualStabilityProvider = visualStabilityProvider;
mAvalancheController = avalancheController;
-
+ mBgHandler = bgHandler;
updateResources();
configurationController.addCallback(new ConfigurationController.ConfigurationListener() {
@Override
@@ -401,7 +405,11 @@
// Waiting HUNs in AvalancheController are still promoted to the HUN section and thus
// seen in open shade; clear them so we don't show them again when the shade closes and
// reordering is allowed again.
- mAvalancheController.logDroppedHuns(mAvalancheController.getWaitingKeys().size());
+ int waitingKeysSize = mAvalancheController.getWaitingKeys().size();
+ mBgHandler.post(() -> {
+ // Do this in the background to avoid missing frames when closing the shade
+ mAvalancheController.logDroppedHuns(waitingKeysSize);
+ });
mAvalancheController.clearNext();
// In open shade the first HUN is pinned, and visual stability logic prevents us from
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt
new file mode 100644
index 0000000..9f76429
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper.HeadsUpNotificationViewController
+
+/** Empty impl of [HeadsUpNotificationViewController] for use with Scene Container */
+class HeadsUpNotificationViewControllerEmptyImpl : HeadsUpNotificationViewController {
+ override fun setHeadsUpDraggingStartingHeight(startHeight: Int) {}
+
+ override fun setTrackedHeadsUp(expandableNotificationRow: ExpandableNotificationRow?) {}
+
+ override fun startExpand(
+ newX: Float,
+ newY: Float,
+ startTracking: Boolean,
+ expandedHeight: Float
+ ) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 198272e..7f16e18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -23,6 +23,7 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.Gefingerpoken;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -122,9 +123,14 @@
+ mPickedChild.getTranslationY());
mPanel.setHeadsUpDraggingStartingHeight(startHeight);
mPanel.startExpand(x, y, true /* startTracking */, startHeight);
- // This call needs to be after the expansion start otherwise we will get a
- // flicker of one frame as it's not expanded yet.
- mHeadsUpManager.unpinAll(true);
+
+ // TODO(b/340514839): Figure out where to move this side effect in flexiglass
+ if (!SceneContainerFlag.isEnabled()) {
+ // This call needs to be after the expansion start otherwise we will get a
+ // flicker of one frame as it's not expanded yet.
+ mHeadsUpManager.unpinAll(true);
+ }
+
clearNotificationEffects();
endMotion();
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
index 8a45ec1..4aece3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
@@ -42,7 +42,7 @@
}
override fun onViewAttached() {
- if (!smartspaceRelocateToBottom() || !smartspaceController.isEnabled()) {
+ if (!smartspaceRelocateToBottom() || !smartspaceController.isEnabled) {
return
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
index e96326a..bcb613f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -232,6 +232,7 @@
skipLockscreenChecks: Boolean,
fillInIntent: Intent?,
extraOptions: Bundle?,
+ customMessage: String?,
) {
val animationController =
if (associatedView is ExpandableNotificationRow) {
@@ -340,6 +341,7 @@
afterKeyguardGone = willLaunchResolverActivity,
dismissShade = collapse,
willAnimateOnKeyguard = animate,
+ customMessage = customMessage,
)
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index eec617b..a33996b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -19,8 +19,8 @@
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
import android.content.Context;
import android.graphics.Rect;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index ae3f923..6676a7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -23,6 +23,7 @@
import android.view.View;
import com.android.systemui.res.R;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
public final class PhoneStatusBarTransitions extends BarTransitions {
private static final float ICON_ALPHA_WHEN_NOT_OPAQUE = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java
index 29c1372..25b8bfe0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java
@@ -16,11 +16,11 @@
package com.android.systemui.statusbar.phone;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_WARNING;
import static com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.OPERATOR_NAME_VIEW;
import android.annotation.NonNull;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index b40bf56..0316b0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -77,9 +77,9 @@
import com.android.systemui.keyguard.shared.model.KeyguardDone;
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.TaskbarDelegate;
+import com.android.systemui.navigationbar.views.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 0218784..45aee5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -29,6 +29,7 @@
import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
import android.view.WindowInsets;
+import androidx.annotation.VisibleForTesting;
import com.android.compose.animation.scene.ObservableTransitionState;
import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.Dumpable;
@@ -69,6 +70,7 @@
private boolean mIsStatusBarExpanded = false;
private boolean mIsIdleOnGone = true;
+ private boolean mIsRemoteUserInteractionOngoing = false;
private boolean mShouldAdjustInsets = false;
private View mNotificationShadeWindowView;
private View mNotificationPanelView;
@@ -133,6 +135,9 @@
javaAdapter.alwaysCollectFlow(
sceneInteractor.get().getTransitionState(),
this::onSceneChanged);
+ javaAdapter.alwaysCollectFlow(
+ sceneInteractor.get().isRemoteUserInteractionOngoing(),
+ this::onRemoteUserInteractionOngoingChanged);
} else {
javaAdapter.alwaysCollectFlow(
shadeInteractor.isAnyExpanded(),
@@ -179,6 +184,13 @@
}
}
+ private void onRemoteUserInteractionOngoingChanged(Boolean ongoing) {
+ if (ongoing != mIsRemoteUserInteractionOngoing) {
+ mIsRemoteUserInteractionOngoing = ongoing;
+ updateTouchableRegion();
+ }
+ }
+
/**
* Calculates the touch region needed for heads up notifications, taking into consideration
* any existing display cutouts (notch)
@@ -276,13 +288,15 @@
* Helper to let us know when calculating the region is not needed because we know the entire
* screen needs to be touchable.
*/
- private boolean shouldMakeEntireScreenTouchable() {
+ @VisibleForTesting
+ boolean shouldMakeEntireScreenTouchable() {
// The touchable region is always the full area when expanded, whether we're showing the
// shade or the bouncer. It's also fully touchable when the screen off animation is playing
// since we don't want stray touches to go through the light reveal scrim to whatever is
// underneath.
return mIsStatusBarExpanded
- || (SceneContainerFlag.isEnabled() && !mIsIdleOnGone)
+ || (SceneContainerFlag.isEnabled()
+ && (!mIsIdleOnGone || mIsRemoteUserInteractionOngoing))
|| mPrimaryBouncerInteractor.isShowing().getValue()
|| mAlternateBouncerInteractor.isVisibleState()
|| mUnlockedScreenOffAnimationController.isAnimationPlaying();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 3d8090d..aced0be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -14,6 +14,8 @@
package com.android.systemui.statusbar.phone.fragment;
+import static com.android.systemui.statusbar.phone.fragment.StatusBarVisibilityModel.createHiddenModel;
+
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.Fragment;
@@ -46,6 +48,7 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
import com.android.systemui.statusbar.CommandQueue;
@@ -205,6 +208,13 @@
private boolean mTransitionFromLockscreenToDreamStarted = false;
/**
+ * True if the current scene allows the home status bar (aka this status bar) to be shown, and
+ * false if the current scene should never show the home status bar. Only used if the scene
+ * container is enabled.
+ */
+ private boolean mHomeStatusBarAllowedByScene = true;
+
+ /**
* True if there's an active ongoing activity that should be showing a chip and false otherwise.
*/
private boolean mHasOngoingActivity;
@@ -522,6 +532,13 @@
mHasOngoingActivity = hasOngoingActivity;
updateStatusBarVisibilities(/* animate= */ true);
}
+
+ @Override
+ public void onIsHomeStatusBarAllowedBySceneChanged(
+ boolean isHomeStatusBarAllowedByScene) {
+ mHomeStatusBarAllowedByScene = isHomeStatusBarAllowedByScene;
+ updateStatusBarVisibilities(/* animate= */ true);
+ }
};
@Override
@@ -580,17 +597,22 @@
boolean headsUpVisible =
mStatusBarFragmentComponent.getHeadsUpAppearanceController().shouldBeVisible();
- if (!mKeyguardStateController.isLaunchTransitionFadingAway()
- && !mKeyguardStateController.isKeyguardFadingAway()
- && shouldHideStatusBar()
- && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
- && headsUpVisible)) {
- // Hide everything
- return new StatusBarVisibilityModel(
- /* showClock= */ false,
- /* showNotificationIcons= */ false,
- /* showOngoingActivityChip= */ false,
- /* showSystemInfo= */ false);
+ if (SceneContainerFlag.isEnabled()) {
+ // With the scene container, only use the value calculated by the view model to
+ // determine if the status bar needs hiding.
+ if (!mHomeStatusBarAllowedByScene) {
+ return createHiddenModel();
+ }
+ } else {
+ // Without the scene container, use our old, mildly-hacky logic to determine if the
+ // status bar needs hiding.
+ if (!mKeyguardStateController.isLaunchTransitionFadingAway()
+ && !mKeyguardStateController.isKeyguardFadingAway()
+ && shouldHideStatusBar()
+ && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+ && headsUpVisible)) {
+ return createHiddenModel();
+ }
}
boolean showClock = externalModel.getShowClock() && !headsUpVisible;
@@ -698,7 +720,7 @@
}
private void hideEndSideContent(boolean animate) {
- if (!animate) {
+ if (!animate || !mAnimationsEnabled) {
mEndSideAlphaController.setAlpha(/*alpha*/ 0f, SOURCE_OTHER);
} else {
mEndSideAlphaController.animateToAlpha(/*alpha*/ 0f, SOURCE_OTHER, FADE_OUT_DURATION,
@@ -707,7 +729,7 @@
}
private void showEndSideContent(boolean animate) {
- if (!animate) {
+ if (!animate || !mAnimationsEnabled) {
mEndSideAlphaController.setAlpha(1f, SOURCE_OTHER);
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt
index fe24fae..9255e63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt
@@ -36,6 +36,17 @@
return createModelFromFlags(DISABLE_NONE, DISABLE2_NONE)
}
+ /** Creates a model that hides every piece of the status bar. */
+ @JvmStatic
+ fun createHiddenModel(): StatusBarVisibilityModel {
+ return StatusBarVisibilityModel(
+ showClock = false,
+ showNotificationIcons = false,
+ showOngoingActivityChip = false,
+ showSystemInfo = false,
+ )
+ }
+
/**
* Given a set of disabled flags, converts them into the correct visibility statuses.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index 50649a8..2c48487 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -29,7 +29,8 @@
* @property startTimeMs the time that the phone call started, based on the notification's
* `when` field. Importantly, this time is relative to
* [com.android.systemui.util.time.SystemClock.currentTimeMillis], **not**
- * [com.android.systemui.util.time.SystemClock.elapsedRealtime].
+ * [com.android.systemui.util.time.SystemClock.elapsedRealtime]. This value can be 0 if the
+ * user has started an outgoing call that hasn't been answered yet - see b/192379214.
* @property intent the intent associated with the call notification.
*/
data class InCall(val startTimeMs: Long, val intent: PendingIntent?) : OngoingCallModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index 9449659..62bd8ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -349,6 +349,7 @@
false
}
}
+ .flowOn(bgDispatcher)
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val carrierId =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
index 68983a1..ae1898b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
@@ -30,6 +30,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.chips.ui.binder.ChipChronometerBinder
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
@@ -108,6 +109,9 @@
setChipMainContent(chipModel, chipTextView, chipTimeView)
chipView.setOnClickListener(chipModel.onClickListener)
+ // Accessibility
+ setChipAccessibility(chipModel, chipView)
+
// Colors
val textColor = chipModel.colors.text(chipContext)
chipIconView.imageTintList = ColorStateList.valueOf(textColor)
@@ -116,6 +120,7 @@
(chipBackgroundView.background as GradientDrawable).color =
chipModel.colors.background(chipContext)
+ // Notify listeners
listener.onOngoingActivityStatusChanged(
hasOngoingActivity = true
)
@@ -132,6 +137,14 @@
}
}
}
+
+ if (SceneContainerFlag.isEnabled) {
+ launch {
+ viewModel.isHomeStatusBarAllowedByScene.collect {
+ listener.onIsHomeStatusBarAllowedBySceneChanged(it)
+ }
+ }
+ }
}
}
}
@@ -157,6 +170,13 @@
chipTextView.visibility = View.GONE
}
+ is OngoingActivityChipModel.Shown.IconOnly -> {
+ chipTextView.visibility = View.GONE
+ // The Chronometer should be stopped to prevent leaks -- see b/192243808 and
+ // [Chronometer.start].
+ chipTimeView.stop()
+ chipTimeView.visibility = View.GONE
+ }
}
updateChipTextPadding(chipModel, chipTextView, chipTimeView)
}
@@ -191,6 +211,19 @@
this.setPaddingRelative(/* start= */ 0, paddingTop, paddingEnd, paddingBottom)
}
+ private fun setChipAccessibility(chipModel: OngoingActivityChipModel.Shown, chipView: View) {
+ when (chipModel) {
+ is OngoingActivityChipModel.Shown.Countdown -> {
+ // Set as assertive so talkback will announce the countdown
+ chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
+ }
+ is OngoingActivityChipModel.Shown.Timer,
+ is OngoingActivityChipModel.Shown.IconOnly -> {
+ chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE
+ }
+ }
+ }
+
private fun animateLightsOutView(view: View, visible: Boolean) {
view.animate().cancel()
@@ -235,4 +268,10 @@
/** Called when the status of the ongoing activity chip (active or not active) has changed. */
fun onOngoingActivityStatusChanged(hasOngoingActivity: Boolean)
+
+ /**
+ * Called when the scene state has changed such that the home status bar is newly allowed or no
+ * longer allowed. See [CollapsedStatusBarViewModel.isHomeStatusBarAllowedByScene].
+ */
+ fun onIsHomeStatusBarAllowedBySceneChanged(isHomeStatusBarAllowedByScene: Boolean)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
index 95d9248..d6c3834 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
@@ -24,6 +24,9 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
@@ -65,6 +68,12 @@
val ongoingActivityChip: StateFlow<OngoingActivityChipModel>
/**
+ * True if the current scene can show the home status bar (aka this status bar), and false if
+ * the current scene should never show the home status bar.
+ */
+ val isHomeStatusBarAllowedByScene: StateFlow<Boolean>
+
+ /**
* Apps can request a low profile mode [android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE] where
* status bar and navigation icons dim. In this mode, a notification dot appears where the
* notification icons would appear if they would be shown outside of this mode.
@@ -83,6 +92,8 @@
private val lightsOutInteractor: LightsOutInteractor,
private val notificationsInteractor: ActiveNotificationsInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ sceneInteractor: SceneInteractor,
+ sceneContainerOcclusionInteractor: SceneContainerOcclusionInteractor,
ongoingActivityChipsViewModel: OngoingActivityChipsViewModel,
@Application coroutineScope: CoroutineScope,
) : CollapsedStatusBarViewModel {
@@ -99,6 +110,20 @@
override val ongoingActivityChip = ongoingActivityChipsViewModel.chip
+ override val isHomeStatusBarAllowedByScene: StateFlow<Boolean> =
+ combine(
+ sceneInteractor.currentScene,
+ sceneContainerOcclusionInteractor.invisibleDueToOcclusion,
+ ) { currentScene, isOccluded ->
+ // All scenes have their own status bars, so we should only show the home status bar
+ // if we're not in a scene. The one exception: If the scene is occluded, then the
+ // occluding app needs to show the status bar. (Fullscreen apps actually won't show
+ // the status bar but that's handled with the rest of our fullscreen app logic,
+ // which lives elsewhere.)
+ currentScene == Scenes.Gone || isOccluded
+ }
+ .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)
+
override fun areNotificationsLightsOut(displayId: Int): Flow<Boolean> =
if (NotificationsLiveDataStoreRefactor.isUnexpectedlyInLegacyMode()) {
emptyFlow()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
index fad5df8..220e729 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
@@ -834,6 +834,7 @@
* @return true if the notification is sticky
*/
public boolean isSticky() {
+ if (mEntry == null) return false;
return (mEntry.isRowPinned() && mExpanded)
|| mRemoteInputActive
|| hasFullScreenIntent(mEntry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 1fc7bf4..31776cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -115,7 +115,7 @@
private final SendButtonTextWatcher mTextWatcher;
private final TextView.OnEditorActionListener mEditorActionHandler;
private final ArrayList<Runnable> mOnSendListeners = new ArrayList<>();
- private final ArrayList<Consumer<Boolean>> mOnVisibilityChangedListeners = new ArrayList<>();
+ private Consumer<Boolean> mOnVisibilityChangedListener = null;
private final ArrayList<OnFocusChangeListener> mEditTextFocusChangeListeners =
new ArrayList<>();
@@ -733,24 +733,17 @@
* {@link #getVisibility()} would return {@link View#VISIBLE}, and {@code false} it would return
* any other value.
*/
- public void addOnVisibilityChangedListener(Consumer<Boolean> listener) {
- mOnVisibilityChangedListeners.add(listener);
- }
-
- /**
- * Unregister a listener previously registered via
- * {@link #addOnVisibilityChangedListener(Consumer)}.
- */
- public void removeOnVisibilityChangedListener(Consumer<Boolean> listener) {
- mOnVisibilityChangedListeners.remove(listener);
+ public void setOnVisibilityChangedListener(Consumer<Boolean> listener) {
+ mOnVisibilityChangedListener = listener;
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (changedView == this) {
- for (Consumer<Boolean> listener : new ArrayList<>(mOnVisibilityChangedListeners)) {
- listener.accept(visibility == VISIBLE);
+ final Consumer<Boolean> visibilityChangedListener = mOnVisibilityChangedListener;
+ if (visibilityChangedListener != null) {
+ visibilityChangedListener.accept(visibility == VISIBLE);
}
// Hide soft-keyboard when the input view became invisible
// (i.e. The notification shade collapsed by pressing the home key)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
index 3e01180..4869114 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
@@ -20,7 +20,8 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.shared.model.StatusBarState
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.policy.BatteryController
@@ -48,6 +49,7 @@
constructor(
@Application scope: CoroutineScope,
headsUpNotificationInteractor: HeadsUpNotificationInteractor,
+ sceneInteractor: SceneInteractor,
keyguardInteractor: KeyguardInteractor,
keyguardStatusBarInteractor: KeyguardStatusBarInteractor,
batteryController: BatteryController,
@@ -55,11 +57,11 @@
/** True if this view should be visible and false otherwise. */
val isVisible: StateFlow<Boolean> =
combine(
+ sceneInteractor.currentScene,
keyguardInteractor.isDozing,
- keyguardInteractor.statusBarState,
headsUpNotificationInteractor.showHeadsUpStatusBar,
- ) { isDozing, statusBarState, showHeadsUpStatusBar ->
- !isDozing && statusBarState == StatusBarState.KEYGUARD && !showHeadsUpStatusBar
+ ) { currentScene, isDozing, showHeadsUpStatusBar ->
+ currentScene == Scenes.Lockscreen && !isDozing && !showHeadsUpStatusBar
}
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 2797b8d..e9f4374 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -36,10 +36,10 @@
import com.android.internal.logging.InstanceId
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.UiEventLogger
-import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.log.DebugLogger.debugLog
+import com.android.systemui.res.R
import com.android.systemui.shared.hardware.hasInputDevice
import com.android.systemui.shared.hardware.isAnyStylusSource
import com.android.systemui.util.NotificationChannels
@@ -65,8 +65,10 @@
private var batteryCapacity = 1.0f
private var suppressed = false
private var instanceId: InstanceId? = null
- @VisibleForTesting var inputDeviceId: Int? = null
- private set
+ @VisibleForTesting
+ var inputDeviceId: Int? = null
+ private set
+
@VisibleForTesting var instanceIdSequence = InstanceIdSequence(1 shl 13)
fun init() {
@@ -113,7 +115,7 @@
inputDeviceId = deviceId
if (batteryState.capacity == batteryCapacity || batteryState.capacity <= 0f)
return@updateBattery
-
+ // Note that batteryState.capacity == NaN will fall through to here
batteryCapacity = batteryState.capacity
debugLog {
"Updating notification battery state to $batteryCapacity " +
@@ -172,7 +174,7 @@
}
private fun isBatteryBelowThreshold(): Boolean {
- return batteryCapacity <= LOW_BATTERY_THRESHOLD
+ return !batteryCapacity.isNaN() && batteryCapacity <= LOW_BATTERY_THRESHOLD
}
private fun hasConnectedBluetoothStylus(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 4963aae..c7fc445 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -202,8 +202,8 @@
}
boolean currentUser = userId == mUserTracker.getUserId();
boolean isAsleep = themeOverlayControllerWakefulnessDeprecation()
- ? mKeyguardTransitionInteractor.isFinishedInStateWhereValue(
- KeyguardState.Companion::deviceIsAsleepInState)
+ ? KeyguardState.Companion.deviceIsAsleepInState(
+ mKeyguardTransitionInteractor.getFinishedState())
: mWakefulnessLifecycle.getWakefulness() != WAKEFULNESS_ASLEEP;
if (currentUser && !mAcceptColorEvents && isAsleep) {
@@ -525,7 +525,7 @@
if (themeOverlayControllerWakefulnessDeprecation()) {
mJavaAdapter.alwaysCollectFlow(
- mKeyguardTransitionInteractor.isFinishedInState(KeyguardState.DOZING),
+ mKeyguardTransitionInteractor.isFinishedIn(KeyguardState.DOZING),
isFinishedInDozing -> {
if (isFinishedInDozing) whenAsleepHandler.run();
});
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index ec6f862..fb40235 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -14,18 +14,18 @@
package com.android.systemui.tuner;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_END;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_START;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_IMAGE_DELIM;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.MENU_IME_ROTATE;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAVSPACE;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_LEFT;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_RIGHT;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_VIEWS;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractButton;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractImage;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractKeycode;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_CODE_END;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_CODE_START;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_IMAGE_DELIM;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.MENU_IME_ROTATE;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAVSPACE;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_LEFT;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_RIGHT;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_VIEWS;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractButton;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractImage;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractKeycode;
import android.annotation.Nullable;
import android.app.AlertDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
index 8c46f9a..28ac2c0 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
@@ -106,3 +106,13 @@
): Flow<R> {
return combine(flow1, flow2, flow3, trifunction)
}
+
+fun <T1, T2, T3, T4, R> combineFlows(
+ flow: Flow<T1>,
+ flow2: Flow<T2>,
+ flow3: Flow<T3>,
+ flow4: Flow<T4>,
+ transform: (T1, T2, T3, T4) -> R
+): Flow<R> {
+ return combine(flow, flow2, flow3, flow4, transform)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
index d10554f..b836016 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
@@ -20,13 +20,16 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Tracing
+import com.android.systemui.dagger.qualifiers.UiBackground
import dagger.Module
import dagger.Provides
+import java.util.concurrent.Executor
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.newFixedThreadPoolContext
import kotlinx.coroutines.plus
@@ -83,4 +86,25 @@
): CoroutineContext {
return bgCoroutineDispatcher + tracingCoroutineContext
}
+
+ /** Coroutine dispatcher for background operations on for UI. */
+ @Provides
+ @SysUISingleton
+ @UiBackground
+ @Deprecated(
+ "Use @UiBackground CoroutineContext instead",
+ ReplaceWith("uiBgCoroutineContext()", "kotlin.coroutines.CoroutineContext")
+ )
+ fun uiBgDispatcher(@UiBackground uiBgExecutor: Executor): CoroutineDispatcher =
+ uiBgExecutor.asCoroutineDispatcher()
+
+ @Provides
+ @UiBackground
+ @SysUISingleton
+ fun uiBgCoroutineContext(
+ @Tracing tracingCoroutineContext: CoroutineContext,
+ @UiBackground uiBgCoroutineDispatcher: CoroutineDispatcher,
+ ): CoroutineContext {
+ return uiBgCoroutineDispatcher + tracingCoroutineContext
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
index 42389f0..4438763 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
@@ -23,16 +23,23 @@
import android.net.Uri;
import android.provider.Settings;
+import com.android.systemui.dagger.qualifiers.Background;
+
+import kotlinx.coroutines.CoroutineDispatcher;
+
import javax.inject.Inject;
// use UserHandle.USER_SYSTEM everywhere
@SuppressLint("StaticSettingsProvider")
class GlobalSettingsImpl implements GlobalSettings {
private final ContentResolver mContentResolver;
+ private final CoroutineDispatcher mBgDispatcher;
@Inject
- GlobalSettingsImpl(ContentResolver contentResolver) {
+ GlobalSettingsImpl(ContentResolver contentResolver,
+ @Background CoroutineDispatcher bgDispatcher) {
mContentResolver = contentResolver;
+ mBgDispatcher = bgDispatcher;
}
@Override
@@ -46,6 +53,11 @@
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mBgDispatcher;
+ }
+
+ @Override
public String getString(String name) {
return Settings.Global.getString(mContentResolver, name);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
index 6532ce8..38ad5d0 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
@@ -22,18 +22,24 @@
import androidx.annotation.NonNull;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.settings.UserTracker;
+import kotlinx.coroutines.CoroutineDispatcher;
+
import javax.inject.Inject;
class SecureSettingsImpl implements SecureSettings {
private final ContentResolver mContentResolver;
private final UserTracker mUserTracker;
+ private final CoroutineDispatcher mBgDispatcher;
@Inject
- SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+ SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+ @Background CoroutineDispatcher bgDispatcher) {
mContentResolver = contentResolver;
mUserTracker = userTracker;
+ mBgDispatcher = bgDispatcher;
}
@Override
@@ -52,6 +58,11 @@
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mBgDispatcher;
+ }
+
+ @Override
public String getStringForUser(String name, int userHandle) {
return Settings.Secure.getStringForUser(mContentResolver, name,
getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
index d92127c..160ae86 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
@@ -20,6 +20,10 @@
import android.net.Uri
import android.provider.Settings.SettingNotFoundException
import com.android.app.tracing.TraceUtils.trace
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Used to interact with mainly with Settings.Global, but can also be used for Settings.System and
@@ -40,6 +44,12 @@
fun getContentResolver(): ContentResolver
/**
+ * Returns the background [CoroutineDispatcher] that the async APIs will use for a specific
+ * implementation.
+ */
+ val backgroundDispatcher: CoroutineDispatcher
+
+ /**
* Construct the content URI for a particular name/value pair, useful for monitoring changes
* with a ContentObserver.
*
@@ -57,6 +67,29 @@
registerContentObserverSync(getUriFor(name), settingsObserver)
}
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(name: String, settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverSync(getUriFor(name), settingsObserver)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ fun registerContentObserverAsync(name: String, settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(getUriFor(name), settingsObserver)
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver].' */
fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) =
registerContentObserverSync(uri, false, settingsObserver)
@@ -64,6 +97,27 @@
/**
* Convenience wrapper around [ContentResolver.registerContentObserver].'
*
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) { registerContentObserverSync(uri, settingsObserver) }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(uri, settingsObserver)
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
* Implicitly calls [getUriFor] on the passed in name.
*/
fun registerContentObserverSync(
@@ -72,6 +126,37 @@
settingsObserver: ContentObserver
) = registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ fun registerContentObserverAsync(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver].' */
fun registerContentObserverSync(
uri: Uri,
@@ -84,6 +169,37 @@
}
}
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+ * registration happens on a worker thread. Caller may wrap the API in an async block if they
+ * wish to synchronize execution.
+ */
+ suspend fun registerContentObserver(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserver] for Java usage.
+ */
+ fun registerContentObserverAsync(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+ }
+
/** See [ContentResolver.unregisterContentObserver]. */
fun unregisterContentObserverSync(settingsObserver: ContentObserver) {
trace({ "SP#unregisterObserver" }) {
@@ -92,6 +208,26 @@
}
/**
+ * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+ *
+ * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+ * [ContentObserver] un-registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun unregisterContentObserver(settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) { unregisterContentObserverSync(settingsObserver) }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+ *
+ * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+ * [ContentObserver] registration happens on a worker thread.
+ */
+ fun unregisterContentObserverAsync(settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch { unregisterContentObserver(settingsObserver) }
+
+ /**
* Look up a name in the database.
*
* @param name to look up in the table
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
index 658b299..68cc753 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
@@ -22,18 +22,24 @@
import androidx.annotation.NonNull;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.settings.UserTracker;
+import kotlinx.coroutines.CoroutineDispatcher;
+
import javax.inject.Inject;
class SystemSettingsImpl implements SystemSettings {
private final ContentResolver mContentResolver;
private final UserTracker mUserTracker;
+ private final CoroutineDispatcher mBgCoroutineDispatcher;
@Inject
- SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+ SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+ @Background CoroutineDispatcher bgDispatcher) {
mContentResolver = contentResolver;
mUserTracker = userTracker;
+ mBgCoroutineDispatcher = bgDispatcher;
}
@Override
@@ -52,6 +58,11 @@
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mBgCoroutineDispatcher;
+ }
+
+ @Override
public String getStringForUser(String name, int userHandle) {
return Settings.System.getStringForUser(mContentResolver, name,
getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
index ed65f1a..3bf5b65 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
@@ -16,6 +16,7 @@
package com.android.systemui.util.settings
import android.annotation.UserIdInt
+import android.content.ContentResolver
import android.database.ContentObserver
import android.net.Uri
import android.os.UserHandle
@@ -26,6 +27,9 @@
import com.android.systemui.util.settings.SettingsProxy.Companion.parseFloatOrThrow
import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrThrow
import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrUseDefault
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Used to interact with per-user Settings.Secure and Settings.System settings (but not
@@ -66,6 +70,17 @@
registerContentObserverForUserSync(uri, settingsObserver, userId)
}
+ override suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(uri, settingsObserver, userId)
+ }
+ }
+
+ override fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(uri, settingsObserver, userId)
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver].' */
override fun registerContentObserverSync(
uri: Uri,
@@ -75,6 +90,30 @@
registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
}
+ override suspend fun registerContentObserver(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ override fun registerContentObserverAsync(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+ }
+
/**
* Convenience wrapper around [ContentResolver.registerContentObserver]
*
@@ -88,6 +127,37 @@
registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
}
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ name: String,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(name, settingsObserver, userHandle)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ name: String,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver] */
fun registerContentObserverForUserSync(
uri: Uri,
@@ -98,6 +168,37 @@
}
/**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ uri: Uri,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ uri: Uri,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+ }
+
+ /**
* Convenience wrapper around [ContentResolver.registerContentObserver]
*
* Implicitly calls [getUriFor] on the passed in name.
@@ -116,6 +217,50 @@
)
}
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(
+ name,
+ notifyForDescendants,
+ settingsObserver,
+ userHandle
+ )
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ name: String,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(
+ getUriFor(name),
+ notifyForDescendants,
+ settingsObserver,
+ userHandle
+ )
+ }
+ }
+
/** Convenience wrapper around [ContentResolver.registerContentObserver] */
fun registerContentObserverForUserSync(
uri: Uri,
@@ -136,6 +281,49 @@
}
/**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * suspend API corresponding to [registerContentObserverForUser] to ensure that
+ * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+ * async block if they wish to synchronize execution.
+ */
+ suspend fun registerContentObserverForUser(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) {
+ withContext(backgroundDispatcher) {
+ registerContentObserverForUserSync(
+ uri,
+ notifyForDescendants,
+ settingsObserver,
+ getRealUserHandle(userHandle)
+ )
+ }
+ }
+
+ /**
+ * Convenience wrapper around [ContentResolver.registerContentObserver].'
+ *
+ * API corresponding to [registerContentObserverForUser] for Java usage.
+ */
+ fun registerContentObserverForUserAsync(
+ uri: Uri,
+ notifyForDescendants: Boolean,
+ settingsObserver: ContentObserver,
+ userHandle: Int
+ ) =
+ CoroutineScope(backgroundDispatcher).launch {
+ registerContentObserverForUserSync(
+ uri,
+ notifyForDescendants,
+ settingsObserver,
+ userHandle
+ )
+ }
+
+ /**
* Look up a name in the database.
*
* @param name to look up in the table
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index aee441a..c45f98e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -567,7 +567,7 @@
streamStateW(stream).levelMax = Math.max(1, getAudioManagerStreamMaxVolume(stream));
updateStreamMuteW(stream, mAudio.isStreamMute(stream));
final StreamState ss = streamStateW(stream);
- ss.muteSupported = mAudio.isStreamAffectedByMute(stream);
+ ss.muteSupported = mAudio.isStreamMutableByUi(stream);
ss.name = STREAMS.get(stream);
checkRoutedToBluetoothW(stream);
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
index 1ae5614..2e7b05a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
@@ -32,6 +32,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.volume.shared.VolumeLogger
import dagger.Module
import dagger.Provides
import kotlin.coroutines.CoroutineContext
@@ -58,6 +59,7 @@
contentResolver: ContentResolver,
@Background coroutineContext: CoroutineContext,
@Application coroutineScope: CoroutineScope,
+ volumeLogger: VolumeLogger,
): AudioRepository =
AudioRepositoryImpl(
intentsReceiver,
@@ -65,6 +67,7 @@
contentResolver,
coroutineContext,
coroutineScope,
+ volumeLogger,
)
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
index c18573e..521f608 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
@@ -26,6 +26,7 @@
import com.android.settingslib.volume.shared.model.RingerMode
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.res.R
+import com.android.systemui.volume.panel.shared.VolumePanelLogger
import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -51,6 +52,7 @@
private val context: Context,
private val audioVolumeInteractor: AudioVolumeInteractor,
private val uiEventLogger: UiEventLogger,
+ private val volumePanelLogger: VolumePanelLogger,
) : SliderViewModel {
private val volumeChanges = MutableStateFlow<Int?>(null)
@@ -105,6 +107,7 @@
audioVolumeInteractor.canChangeVolume(audioStream),
audioVolumeInteractor.ringerMode,
) { model, isEnabled, ringerMode ->
+ volumePanelLogger.onVolumeUpdateReceived(audioStream, model.volume)
model.toState(isEnabled, ringerMode)
}
.stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty)
@@ -112,7 +115,10 @@
init {
volumeChanges
.filterNotNull()
- .onEach { audioVolumeInteractor.setVolume(audioStream, it) }
+ .onEach {
+ volumePanelLogger.onSetVolumeRequested(audioStream, it)
+ audioVolumeInteractor.setVolume(audioStream, it)
+ }
.launchIn(coroutineScope)
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt
new file mode 100644
index 0000000..cc513b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.panel.shared
+
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.VolumeLog
+import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
+import javax.inject.Inject
+
+private const val TAG = "SysUI_VolumePanel"
+
+/** Logs events related to the Volume Panel. */
+@VolumePanelScope
+class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: LogBuffer) {
+
+ fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = audioStream.toString()
+ int1 = volume
+ },
+ { "Set volume: stream=$str1 volume=$int1" }
+ )
+ }
+
+ fun onVolumeUpdateReceived(audioStream: AudioStream, volume: Int) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = audioStream.toString()
+ int1 = volume
+ },
+ { "Volume update received: stream=$str1 volume=$int1" }
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt
new file mode 100644
index 0000000..869a82a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.shared
+
+import com.android.settingslib.volume.data.repository.AudioRepositoryImpl
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.settingslib.volume.shared.model.AudioStreamModel
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.VolumeLog
+import javax.inject.Inject
+
+private const val TAG = "SysUI_Volume"
+
+/** Logs general System UI volume events. */
+@SysUISingleton
+class VolumeLogger @Inject constructor(@VolumeLog private val logBuffer: LogBuffer) :
+ AudioRepositoryImpl.Logger {
+
+ override fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = audioStream.toString()
+ int1 = volume
+ },
+ { "Set volume: stream=$str1 volume=$int1" }
+ )
+ }
+
+ override fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = audioStream.toString()
+ int1 = model.volume
+ },
+ { "Volume update received: stream=$str1 volume=$int1" }
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index cb61534..8457bdb 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -51,7 +51,7 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index ec9b5cf..3f1ec85 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -20,8 +20,9 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -66,6 +67,7 @@
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
import com.android.wm.shell.pip.Pip;
+import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.sysui.ShellInterface;
@@ -249,7 +251,25 @@
pip.showPictureInPictureMenu();
}
});
+ pip.registerPipTransitionCallback(
+ new PipTransitionController.PipTransitionCallback() {
+ @Override
+ public void onPipTransitionStarted(int direction, Rect pipBounds) {
+ mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING, true)
+ .commitUpdate(mDisplayTracker.getDefaultDisplayId());
+ }
+ @Override
+ public void onPipTransitionFinished(int direction) {
+ mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING, false)
+ .commitUpdate(mDisplayTracker.getDefaultDisplayId());
+ }
+
+ @Override
+ public void onPipTransitionCanceled(int direction) {
+ // No op.
+ }
+ }, mSysUiMainExecutor);
mSysUiState.addCallback(sysUiStateFlag -> {
mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0;
pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
index 8858d13..48f6cc4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
@@ -28,6 +28,7 @@
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
@@ -40,6 +41,7 @@
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
+import dagger.Lazy
import java.io.PrintWriter
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -51,7 +53,6 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
-import dagger.Lazy
@SmallTest
class ActiveUnlockConfigTest : SysuiTestCase() {
@@ -111,6 +112,48 @@
ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
)
)
+ assertFalse(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+ )
+ )
+ assertTrue(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
+ )
+ )
+ assertTrue(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL
+ )
+ )
+ }
+
+ @Test
+ fun onUnlockIntentLegacySettingChanged() {
+ // GIVEN no active unlock settings enabled
+ assertFalse(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+ )
+ )
+
+ // WHEN unlock on unlock intent legacy is allowed
+ secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY, 1, currentUser)
+ updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY))
+
+ // THEN active unlock triggers allowed on unlock_intent_legacy, unlock_intent,
+ // AND biometric fail
+ assertFalse(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
+ )
+ )
+ assertTrue(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+ )
+ )
assertTrue(
activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
@@ -132,16 +175,21 @@
)
)
- // WHEN unlock on biometric failed is allowed
+ // WHEN unlock on unlock intent is allowed
secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT, 1, currentUser)
updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT))
- // THEN active unlock triggers allowed on: biometric failure ONLY
+ // THEN active unlock triggers allowed on: unlock intent AND biometric failure
assertFalse(
activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
)
)
+ assertFalse(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+ )
+ )
assertTrue(
activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
@@ -184,6 +232,11 @@
)
assertFalse(
activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+ )
+ )
+ assertFalse(
+ activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
)
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
index 64c162f..639b53b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
@@ -46,6 +46,7 @@
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleCoroutineScope;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
@@ -159,7 +160,9 @@
ArgumentCaptor<LifecycleObserver> observerCaptor =
ArgumentCaptor.forClass(LifecycleObserver.class);
verify(mLifecycleRegistry, atLeast(1)).addObserver(observerCaptor.capture());
- mLifecycleObservers.addAll(observerCaptor.getAllValues());
+ mLifecycleObservers.addAll(observerCaptor.getAllValues().stream().filter(
+ lifecycleObserver -> !(lifecycleObserver instanceof LifecycleCoroutineScope))
+ .toList());
updateLifecycle(Lifecycle.State.RESUMED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
index a58efd3..30207bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
@@ -23,15 +23,22 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.display.data.repository.DeviceStateRepository
import com.android.systemui.display.data.repository.fakeDeviceStateRepository
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -61,10 +68,11 @@
fun setup() {
interactor =
LogContextInteractorImpl(
- testScope.backgroundScope,
- deviceStateRepository,
- kosmos.keyguardTransitionInteractor,
- udfpsOverlayInteractor,
+ applicationScope = testScope.backgroundScope,
+ deviceStateRepository = deviceStateRepository,
+ keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
+ udfpsOverlayInteractor = udfpsOverlayInteractor,
+ deviceEntryInteractor = { kosmos.deviceEntryInteractor },
)
}
@@ -135,7 +143,57 @@
}
@Test
- fun displayStateChanges() =
+ @EnableSceneContainer
+ fun displayStateChanges_withSceneContainer() =
+ testScope.runTest {
+ val displayState = collectLastValue(interactor.displayState)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OFF)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DOZING)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DREAMING)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_SCREENSAVER)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.LOCKSCREEN)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OCCLUDED)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ // Unlock the device.
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
+ kosmos.sceneInteractor.snapToScene(Scenes.Gone, "")
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.GONE)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_UNKNOWN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.UNDEFINED)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_UNKNOWN)
+
+ // Relock the device
+ kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun displayStateChanges_withoutSceneContainer() =
testScope.runTest {
val displayState = collectLastValue(interactor.displayState)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 0ed40e9..97f5efc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.biometrics.ui.kosmos.promptViewmodel
+package com.android.systemui.biometrics.ui.viewmodel
import android.app.ActivityManager.RunningTaskInfo
import android.content.ComponentName
@@ -66,12 +66,6 @@
import com.android.systemui.biometrics.shared.model.toSensorStrength
import com.android.systemui.biometrics.shared.model.toSensorType
import com.android.systemui.biometrics.udfpsUtils
-import com.android.systemui.biometrics.ui.viewmodel.FingerprintStartMode
-import com.android.systemui.biometrics.ui.viewmodel.PromptMessage
-import com.android.systemui.biometrics.ui.viewmodel.PromptPosition
-import com.android.systemui.biometrics.ui.viewmodel.PromptSize
-import com.android.systemui.biometrics.ui.viewmodel.iconProvider
-import com.android.systemui.biometrics.ui.viewmodel.promptViewModel
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
index ddf69b5..c2173c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
@@ -132,7 +132,7 @@
public void complicationAvailability_serviceNotAvailable_noFavorites_doNotAddComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
- mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+ mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(false);
@@ -145,7 +145,7 @@
public void complicationAvailability_serviceAvailable_noFavorites_doNotAddComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
- mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+ mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(false);
@@ -158,7 +158,7 @@
public void complicationAvailability_serviceAvailable_noFavorites_panel_addComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
- mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+ mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(false);
@@ -171,7 +171,7 @@
public void complicationAvailability_serviceNotAvailable_haveFavorites_doNotAddComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
- mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+ mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(true);
@@ -184,7 +184,7 @@
public void complicationAvailability_serviceAvailable_haveFavorites_addComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
- mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+ mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(true);
@@ -197,7 +197,7 @@
public void complicationAvailability_checkAvailabilityWhenDreamOverlayBecomesActive() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
- mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+ mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setServiceAvailable(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index 1c327af..f34058b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -20,6 +20,7 @@
import android.os.Looper
import android.testing.TestableLooper
import android.view.Display
+import android.view.Display.DEFAULT_DISPLAY
import android.view.Display.TYPE_EXTERNAL
import android.view.Display.TYPE_INTERNAL
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -27,7 +28,6 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -45,6 +45,7 @@
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.kotlin.eq
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@@ -63,8 +64,8 @@
@Before
fun setup() {
- setDisplays(emptyList())
- setAllDisplaysIncludingDisabled()
+ setDisplays(DEFAULT_DISPLAY)
+ setAllDisplaysIncludingDisabled(DEFAULT_DISPLAY)
displayRepository =
DisplayRepositoryImpl(
displayManager,
@@ -81,7 +82,7 @@
testScope.runTest {
val value by latestDisplayFlowValue()
- assertThat(value).isEmpty()
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
verify(displayManager).registerDisplayListener(any(), eq(testHandler), anyLong())
}
@@ -91,7 +92,7 @@
testScope.runTest {
val value by latestDisplayFlowValue()
- assertThat(value).isEmpty()
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
verify(displayManager).registerDisplayListener(any(), eq(testHandler), anyLong())
}
@@ -103,14 +104,14 @@
testScope.runTest {
val firstSubscriber by latestDisplayFlowValue()
- assertThat(firstSubscriber).isEmpty()
+ assertThat(firstSubscriber).hasSize(1) // Default display only
verify(displayManager, times(1))
.registerDisplayListener(displayListener.capture(), eq(testHandler), anyLong())
val innerScope = TestScope()
innerScope.runTest {
val secondSubscriber by latestDisplayFlowValue()
- assertThat(secondSubscriber).isEmpty()
+ assertThat(secondSubscriber).hasSize(1)
// No new registration, just the precedent one.
verify(displayManager, times(1))
@@ -120,7 +121,7 @@
// Let's make sure it has *NOT* been unregistered, as there is still a subscriber.
setDisplays(1)
sendOnDisplayAdded(1)
- assertThat(firstSubscriber?.ids()).containsExactly(1)
+ assertThat(firstSubscriber?.ids()).contains(1)
}
// All subscribers are done, unregister should have been called.
@@ -135,7 +136,7 @@
setDisplays(1)
sendOnDisplayAdded(1)
- assertThat(value?.ids()).containsExactly(1)
+ assertThat(value?.ids()).contains(1)
}
@Test
@@ -152,7 +153,7 @@
setDisplays(1, 2, 3)
sendOnDisplayRemoved(4)
- assertThat(value?.ids()).containsExactly(1, 2, 3)
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY, 1, 2, 3)
}
@Test
@@ -168,7 +169,7 @@
displayListener.value.onDisplayChanged(4)
- assertThat(value?.ids()).containsExactly(1, 2, 3, 4)
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY, 1, 2, 3, 4)
}
@Test
@@ -435,37 +436,29 @@
val defaultDisplayOff by latestDefaultDisplayOffFlowValue()
setDisplays(
listOf(
- display(
- type = TYPE_INTERNAL,
- id = Display.DEFAULT_DISPLAY,
- state = Display.STATE_OFF
- )
+ display(type = TYPE_INTERNAL, id = DEFAULT_DISPLAY, state = Display.STATE_OFF)
)
)
- displayListener.value.onDisplayChanged(Display.DEFAULT_DISPLAY)
+ displayListener.value.onDisplayChanged(DEFAULT_DISPLAY)
assertThat(defaultDisplayOff).isTrue()
setDisplays(
listOf(
- display(
- type = TYPE_INTERNAL,
- id = Display.DEFAULT_DISPLAY,
- state = Display.STATE_ON
- )
+ display(type = TYPE_INTERNAL, id = DEFAULT_DISPLAY, state = Display.STATE_ON)
)
)
- displayListener.value.onDisplayChanged(Display.DEFAULT_DISPLAY)
+ displayListener.value.onDisplayChanged(DEFAULT_DISPLAY)
assertThat(defaultDisplayOff).isFalse()
}
@Test
fun displayFlow_startsWithDefaultDisplayBeforeAnyEvent() =
testScope.runTest {
- setDisplays(Display.DEFAULT_DISPLAY)
+ setDisplays(DEFAULT_DISPLAY)
val value by latestDisplayFlowValue()
- assertThat(value?.ids()).containsExactly(Display.DEFAULT_DISPLAY)
+ assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
}
private fun Iterable<Display>.ids(): List<Int> = map { it.displayId }
@@ -565,6 +558,8 @@
}
private fun setDisplays(vararg ids: Int) {
- setDisplays(ids.map { display(type = TYPE_EXTERNAL, id = it) })
+ // DEFAULT_DISPLAY always there
+ val idsToSet = ids.toSet() + DEFAULT_DISPLAY
+ setDisplays(idsToSet.map { display(type = TYPE_EXTERNAL, id = it) })
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
new file mode 100644
index 0000000..b986c52
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepositoryTest.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.data.repository
+
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
+import com.android.systemui.keyboard.shortcut.shortcutHelperCategoriesRepository
+import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShortcutHelperCategoriesRepositoryTest : SysuiTestCase() {
+ @OptIn(ExperimentalCoroutinesApi::class)
+ private val kosmos = testKosmos().also { it.testDispatcher = UnconfinedTestDispatcher() }
+ private val repo = kosmos.shortcutHelperCategoriesRepository
+ private val helper = kosmos.shortcutHelperTestHelper
+ private val testScope = kosmos.testScope
+
+ @Test
+ fun stateActive_imeShortcuts_shortcutInfoCorrectlyConverted() =
+ testScope.runTest {
+ helper.setImeShortcuts(imeShortcutsGroupWithPreviousLanguageSwitchShortcut)
+ val imeShortcutCategory by collectLastValue(repo.imeShortcutsCategory)
+
+ helper.showFromActivity()
+
+ assertThat(imeShortcutCategory)
+ .isEqualTo(expectedImeShortcutCategoryWithPreviousLanguageSwitchShortcut)
+ }
+
+ @Test
+ fun stateActive_imeShortcuts_onlyUnsupportedShortcuts_discardsAll() =
+ testScope.runTest {
+ helper.setImeShortcuts(imeShortcutsGroupWithUnsupportedShortcutModifiers)
+ val imeShortcutCategory by collectLastValue(repo.imeShortcutsCategory)
+
+ helper.showFromActivity()
+
+ assertThat(imeShortcutCategory).isEqualTo(null)
+ }
+
+ private val switchToPreviousLanguageCommand =
+ ShortcutCommand(
+ listOf(KeyEvent.META_CTRL_ON, KeyEvent.META_SHIFT_ON, KeyEvent.KEYCODE_SPACE)
+ )
+
+ private val expectedImeShortcutCategoryWithDiscardedUnsupportedShortcuts =
+ shortcutCategory(ShortcutCategoryType.IME) { subCategory("input", emptyList()) }
+
+ private val switchToPreviousLanguageKeyboardShortcutInfo =
+ KeyboardShortcutInfo(
+ /* label = */ "switch to previous language",
+ /* keycode = */ switchToPreviousLanguageCommand.keyCodes[2],
+ /* modifiers = */ switchToPreviousLanguageCommand.keyCodes[0] or
+ switchToPreviousLanguageCommand.keyCodes[1],
+ )
+
+ private val expectedImeShortcutCategoryWithPreviousLanguageSwitchShortcut =
+ shortcutCategory(ShortcutCategoryType.IME) {
+ subCategory(
+ "input",
+ listOf(
+ Shortcut(
+ switchToPreviousLanguageKeyboardShortcutInfo.label!!.toString(),
+ listOf(switchToPreviousLanguageCommand)
+ )
+ )
+ )
+ }
+
+ private val imeShortcutsGroupWithPreviousLanguageSwitchShortcut =
+ listOf(
+ KeyboardShortcutGroup(
+ "input",
+ listOf(
+ switchToPreviousLanguageKeyboardShortcutInfo,
+ )
+ )
+ )
+
+ private val shortcutInfoWithUnsupportedModifier =
+ KeyboardShortcutInfo(
+ /* label = */ "unsupported shortcut",
+ /* keycode = */ KeyEvent.KEYCODE_SPACE,
+ /* modifiers = */ 32
+ )
+
+ private val imeShortcutsGroupWithUnsupportedShortcutModifiers =
+ listOf(
+ KeyboardShortcutGroup(
+ "input",
+ listOf(
+ shortcutInfoWithUnsupportedModifier,
+ )
+ )
+ )
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
index 9c9e48e..c00e7e79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
@@ -16,10 +16,18 @@
package com.android.systemui.keyboard.shortcut.domain.interactor
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import com.android.systemui.keyboard.shortcut.shared.model.shortcut
import com.android.systemui.keyboard.shortcut.shortcutHelperCategoriesInteractor
import com.android.systemui.keyboard.shortcut.shortcutHelperMultiTaskingShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource
@@ -31,6 +39,7 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -38,13 +47,25 @@
@RunWith(AndroidJUnit4::class)
class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
+ private val systemShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ private val multitaskingShortcutsSource = FakeKeyboardShortcutGroupsSource()
@OptIn(ExperimentalCoroutinesApi::class)
- private val kosmos = testKosmos().also { it.testDispatcher = UnconfinedTestDispatcher() }
+ private val kosmos =
+ testKosmos().also {
+ it.testDispatcher = UnconfinedTestDispatcher()
+ it.shortcutHelperSystemShortcutsSource = systemShortcutsSource
+ it.shortcutHelperMultiTaskingShortcutsSource = multitaskingShortcutsSource
+ }
private val testScope = kosmos.testScope
private val interactor = kosmos.shortcutHelperCategoriesInteractor
private val helper = kosmos.shortcutHelperTestHelper
- private val systemShortcutsSource = kosmos.shortcutHelperSystemShortcutsSource
- private val multitaskingShortcutsSource = kosmos.shortcutHelperMultiTaskingShortcutsSource
+
+ @Before
+ fun setUp() {
+ // Setting these sources as empty temporarily. Will be populated in follow up CL.
+ systemShortcutsSource.setGroups(emptyList())
+ multitaskingShortcutsSource.setGroups(emptyList())
+ }
@Test
fun categories_emptyByDefault() =
@@ -57,16 +78,12 @@
@Test
fun categories_stateActive_emitsAllCategoriesInOrder() =
testScope.runTest {
+ helper.setImeShortcuts(imeShortcutGroups)
val categories by collectLastValue(interactor.shortcutCategories)
helper.showFromActivity()
- assertThat(categories)
- .containsExactly(
- systemShortcutsSource.systemShortcutsCategory(),
- multitaskingShortcutsSource.multitaskingShortcutCategory()
- )
- .inOrder()
+ assertThat(categories).containsExactly(imeShortcutCategory).inOrder()
}
@Test
@@ -78,4 +95,160 @@
assertThat(categories).isEmpty()
}
+
+ fun categories_stateActive_emitsGroupedShortcuts() =
+ testScope.runTest {
+ helper.setImeShortcuts(imeShortcutsGroupsWithDuplicateLabels)
+ val categories by collectLastValue(interactor.shortcutCategories)
+
+ helper.showFromActivity()
+
+ assertThat(categories).containsExactly(expectedGroupedShortcutCategories)
+ }
+
+ private val switchToNextLanguageShortcut =
+ shortcut(label = "switch to next language") {
+ command(KeyEvent.META_CTRL_ON, KeyEvent.KEYCODE_SPACE)
+ }
+
+ private val switchToNextLanguageKeyboardShortcutInfo =
+ KeyboardShortcutInfo(
+ /* label = */ switchToNextLanguageShortcut.label,
+ /* keycode = */ switchToNextLanguageShortcut.commands[0].keyCodes[1],
+ /* modifiers = */ switchToNextLanguageShortcut.commands[0].keyCodes[0],
+ )
+
+ private val switchToNextLanguageShortcutAlternative =
+ shortcut("switch to next language") {
+ command(KeyEvent.META_CTRL_ON, KeyEvent.KEYCODE_SPACE)
+ }
+
+ private val switchToNextLanguageKeyboardShortcutInfoAlternative =
+ KeyboardShortcutInfo(
+ /* label = */ switchToNextLanguageShortcutAlternative.label,
+ /* keycode = */ switchToNextLanguageShortcutAlternative.commands[0].keyCodes[1],
+ /* modifiers = */ switchToNextLanguageShortcutAlternative.commands[0].keyCodes[0],
+ )
+
+ private val switchToPreviousLanguageShortcut =
+ shortcut("switch to previous language") {
+ command(
+ KeyEvent.META_SHIFT_ON,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ }
+
+ private val switchToPreviousLanguageKeyboardShortcutInfo =
+ KeyboardShortcutInfo(
+ /* label = */ switchToPreviousLanguageShortcut.label,
+ /* keycode = */ switchToPreviousLanguageShortcut.commands[0].keyCodes[1],
+ /* modifiers = */ switchToPreviousLanguageShortcut.commands[0].keyCodes[0],
+ )
+
+ private val switchToPreviousLanguageShortcutAlternative =
+ shortcut("switch to previous language") {
+ command(
+ KeyEvent.META_SHIFT_ON,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ }
+
+ private val switchToPreviousLanguageKeyboardShortcutInfoAlternative =
+ KeyboardShortcutInfo(
+ /* label = */ switchToPreviousLanguageShortcutAlternative.label,
+ /* keycode = */ switchToPreviousLanguageShortcutAlternative.commands[0].keyCodes[1],
+ /* modifiers = */ switchToPreviousLanguageShortcutAlternative.commands[0].keyCodes[0],
+ )
+
+ private val showOnscreenKeyboardShortcut =
+ shortcut(label = "Show on-screen keyboard") {
+ command(KeyEvent.META_ALT_ON, KeyEvent.KEYCODE_K)
+ }
+
+ private val showOnScreenKeyboardShortcutInfo =
+ KeyboardShortcutInfo(
+ /* label = */ showOnscreenKeyboardShortcut.label,
+ /* keycode = */ showOnscreenKeyboardShortcut.commands[0].keyCodes[1],
+ /* modifiers = */ showOnscreenKeyboardShortcut.commands[0].keyCodes[0],
+ )
+
+ private val accessClipboardShortcut =
+ shortcut(label = "Access clipboard") { command(KeyEvent.META_ALT_ON, KeyEvent.KEYCODE_V) }
+
+ private val accessClipboardShortcutInfo =
+ KeyboardShortcutInfo(
+ /* label = */ accessClipboardShortcut.label,
+ /* keycode = */ accessClipboardShortcut.commands[0].keyCodes[1],
+ /* modifiers = */ accessClipboardShortcut.commands[0].keyCodes[0],
+ )
+
+ private val imeShortcutGroups =
+ listOf(
+ KeyboardShortcutGroup(
+ /* label = */ "input",
+ /* shortcutInfoList = */ listOf(
+ switchToNextLanguageKeyboardShortcutInfo,
+ switchToPreviousLanguageKeyboardShortcutInfo
+ )
+ )
+ )
+
+ private val imeShortcutCategory =
+ ShortcutCategory(
+ type = ShortcutCategoryType.IME,
+ subCategories =
+ listOf(
+ ShortcutSubCategory(
+ imeShortcutGroups[0].label.toString(),
+ listOf(switchToNextLanguageShortcut, switchToPreviousLanguageShortcut)
+ )
+ )
+ )
+
+ private val imeShortcutsGroupsWithDuplicateLabels =
+ listOf(
+ KeyboardShortcutGroup(
+ "input",
+ listOf(
+ switchToNextLanguageKeyboardShortcutInfo,
+ switchToNextLanguageKeyboardShortcutInfoAlternative,
+ switchToPreviousLanguageKeyboardShortcutInfo,
+ switchToPreviousLanguageKeyboardShortcutInfoAlternative
+ )
+ ),
+ KeyboardShortcutGroup(
+ "Gboard",
+ listOf(
+ showOnScreenKeyboardShortcutInfo,
+ accessClipboardShortcutInfo,
+ )
+ )
+ )
+
+ private val expectedGroupedShortcutCategories =
+ ShortcutCategory(
+ type = ShortcutCategoryType.IME,
+ subCategories =
+ listOf(
+ ShortcutSubCategory(
+ imeShortcutsGroupsWithDuplicateLabels[0].label.toString(),
+ listOf(
+ switchToNextLanguageShortcut.copy(
+ commands =
+ switchToNextLanguageShortcut.commands +
+ switchToNextLanguageShortcutAlternative.commands
+ ),
+ switchToPreviousLanguageShortcut.copy(
+ commands =
+ switchToPreviousLanguageShortcut.commands +
+ switchToPreviousLanguageShortcutAlternative.commands
+ )
+ ),
+ ),
+ ShortcutSubCategory(
+ imeShortcutsGroupsWithDuplicateLabels[1].label.toString(),
+ listOf(showOnscreenKeyboardShortcut, accessClipboardShortcut),
+ )
+ )
+ )
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 90ac05f..506c5ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -135,7 +135,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
val remoteUserSelectionManager =
@@ -481,8 +480,7 @@
)
}
}
- }
- ?: emptyList()
+ } ?: emptyList()
}
private fun querySlots(): List<Slot> {
@@ -517,8 +515,7 @@
)
}
}
- }
- ?: emptyList()
+ } ?: emptyList()
}
private fun queryAffordances(): List<Affordance> {
@@ -558,8 +555,7 @@
)
}
}
- }
- ?: emptyList()
+ } ?: emptyList()
}
data class Slot(
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 27b9863..f726aae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -7,6 +7,7 @@
import android.graphics.Rect
import android.os.PowerManager
import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import android.view.RemoteAnimationTarget
import android.view.SurfaceControl
@@ -99,6 +100,13 @@
mock(ActivityManager.RunningTaskInfo::class.java), false)
private lateinit var wallpaperTargets: Array<RemoteAnimationTarget>
+ private var surfaceControlLockWp = mock(SurfaceControl::class.java)
+ private var lockWallpaperTarget = RemoteAnimationTarget(
+ 3 /* taskId */, 0, surfaceControlLockWp, false, Rect(), Rect(), 0, Point(), Rect(),
+ Rect(), mock(WindowConfiguration::class.java), false, surfaceControlLockWp,
+ Rect(), mock(ActivityManager.RunningTaskInfo::class.java), false)
+ private lateinit var lockWallpaperTargets: Array<RemoteAnimationTarget>
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -118,6 +126,7 @@
// appear amount setter doesn't short circuit.
remoteAnimationTargets = arrayOf(remoteTarget1)
wallpaperTargets = arrayOf(wallpaperTarget)
+ lockWallpaperTargets = arrayOf(lockWallpaperTarget)
// Set the surface applier to our mock so that we can verify the arguments passed to it.
// This applier does not have any side effects within the unlock animation controller, so
@@ -144,6 +153,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
arrayOf(),
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -177,6 +187,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -199,6 +210,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -219,6 +231,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -242,6 +255,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
true /* requestedShowSurfaceBehindKeyguard */
)
@@ -265,6 +279,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
true /* requestedShowSurfaceBehindKeyguard */
)
@@ -286,6 +301,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -301,6 +317,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
true /* requestedShowSurfaceBehindKeyguard */
)
@@ -317,6 +334,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -325,6 +343,53 @@
}
/**
+ * The canned animation should launch a cross fade when there are different wallpapers on lock
+ * and home screen.
+ */
+ @Test
+ @EnableFlags(Flags.FLAG_FASTER_UNLOCK_TRANSITION)
+ fun manualUnlock_multipleWallpapers() {
+ var lastFadeInAlpha = -1f
+ var lastFadeOutAlpha = -1f
+
+ keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+ arrayOf(remoteTarget1, remoteTarget2),
+ wallpaperTargets,
+ lockWallpaperTargets,
+ 0 /* startTime */,
+ false /* requestedShowSurfaceBehindKeyguard */
+ )
+
+ for (i in 0..10) {
+ clearInvocations(surfaceTransactionApplier)
+ val amount = i / 10f
+
+ keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(amount)
+
+ val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
+ verify(surfaceTransactionApplier, times(2)).scheduleApply(
+ captorSb.capture { sp ->
+ sp.surface == surfaceControlWp || sp.surface == surfaceControlLockWp })
+
+ val fadeInAlpha = captorSb.getLastValue { it.surface == surfaceControlWp }.alpha
+ val fadeOutAlpha = captorSb.getLastValue { it.surface == surfaceControlLockWp }.alpha
+
+ if (amount == 0f) {
+ assertTrue (fadeInAlpha == 0f)
+ assertTrue (fadeOutAlpha == 1f)
+ } else if (amount == 1f) {
+ assertTrue (fadeInAlpha == 1f)
+ assertTrue (fadeOutAlpha == 0f)
+ } else {
+ assertTrue(fadeInAlpha >= lastFadeInAlpha)
+ assertTrue(fadeOutAlpha <= lastFadeOutAlpha)
+ }
+ lastFadeInAlpha = fadeInAlpha
+ lastFadeOutAlpha = fadeOutAlpha
+ }
+ }
+
+ /**
* If we are not wake and unlocking, we expect the unlock animation to play normally.
*/
@Test
@@ -333,6 +398,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
arrayOf(remoteTarget1, remoteTarget2),
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -378,6 +444,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -387,7 +454,7 @@
clearInvocations(surfaceTransactionApplier)
keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f)
- keyguardUnlockAnimationController.setWallpaperAppearAmount(1f)
+ keyguardUnlockAnimationController.setWallpaperAppearAmount(1f, wallpaperTargets)
val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
verify(surfaceTransactionApplier, times(1)).scheduleApply(
@@ -414,6 +481,7 @@
keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
remoteAnimationTargets,
wallpaperTargets,
+ arrayOf(),
0 /* startTime */,
false /* requestedShowSurfaceBehindKeyguard */
)
@@ -423,7 +491,7 @@
clearInvocations(surfaceTransactionApplier)
keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f)
- keyguardUnlockAnimationController.setWallpaperAppearAmount(1f)
+ keyguardUnlockAnimationController.setWallpaperAppearAmount(1f, wallpaperTargets)
val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
verify(surfaceTransactionApplier, times(1)).scheduleApply(
@@ -532,8 +600,8 @@
}
}
- fun getLastValue(): T {
- return allArgs.last()
+ fun getLastValue(predicate: Predicate<T>? = null): T {
+ return if (predicate != null) allArgs.last(predicate::test) else allArgs.last()
}
fun getAllValues(): List<T> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index d2a9c58..7560a97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -63,9 +63,6 @@
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4
-import platform.test.runner.parameterized.Parameters
-import platform.test.runner.parameterized.Parameter
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
@@ -76,6 +73,9 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.Parameter
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@OptIn(ExperimentalCoroutinesApi::class)
@FlakyTest(
@@ -281,7 +281,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
val remoteUserSelectionManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
index 9d06031..fd1bf54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
@@ -63,9 +63,6 @@
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4
-import platform.test.runner.parameterized.Parameters
-import platform.test.runner.parameterized.Parameter
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
@@ -76,6 +73,9 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.Parameter
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@OptIn(ExperimentalCoroutinesApi::class)
@FlakyTest(
@@ -281,7 +281,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
val remoteUserSelectionManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
index 6398a5a..c1bd378 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
@@ -19,26 +19,22 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.keyguard.keyguardUpdateMonitor
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository
-import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
-import com.android.systemui.statusbar.policy.keyguardStateController
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.kotlin.whenever
+import org.junit.runners.JUnit4
@ExperimentalCoroutinesApi
@RunWith(AndroidJUnit4::class)
@@ -54,35 +50,13 @@
fun alternateBouncerTransition_alternateBouncerWindowRequiredTrue() =
testScope.runTest {
mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
- val canShowAlternateBouncer by collectLastValue(underTest.canShowAlternateBouncer)
val alternateBouncerWindowRequired by
collectLastValue(underTest.alternateBouncerWindowRequired)
- givenCanShowAlternateBouncer()
fingerprintPropertyRepository.supportsUdfps()
transitionRepository.sendTransitionSteps(
listOf(
- stepToLockscreen(0f, TransitionState.STARTED),
- stepToLockscreen(.4f),
- stepToLockscreen(1f, TransitionState.FINISHED),
- ),
- testScope,
- )
- assertThat(canShowAlternateBouncer).isTrue()
- transitionRepository.sendTransitionSteps(
- listOf(
- stepFromLockscreenToAlternateBouncer(0f, TransitionState.STARTED),
- stepFromLockscreenToAlternateBouncer(.4f),
- stepFromLockscreenToAlternateBouncer(.6f),
- ),
- testScope,
- )
- assertThat(canShowAlternateBouncer).isTrue()
- assertThat(alternateBouncerWindowRequired).isTrue()
-
- transitionRepository.sendTransitionSteps(
- listOf(
stepFromAlternateBouncer(0f, TransitionState.STARTED),
- stepFromAlternateBouncer(.2f),
+ stepFromAlternateBouncer(.4f),
stepFromAlternateBouncer(.6f),
),
testScope,
@@ -104,21 +78,13 @@
mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
val alternateBouncerWindowRequired by
collectLastValue(underTest.alternateBouncerWindowRequired)
- givenCanShowAlternateBouncer()
fingerprintPropertyRepository.supportsUdfps()
transitionRepository.sendTransitionSteps(
listOf(
- stepToLockscreen(0f, TransitionState.STARTED),
- stepToLockscreen(.4f),
- stepToLockscreen(1f, TransitionState.FINISHED),
- ),
- testScope,
- )
- transitionRepository.sendTransitionSteps(
- listOf(
- stepFromLockscreenToAlternateBouncer(0f, TransitionState.STARTED),
- stepFromLockscreenToAlternateBouncer(.4f),
- stepFromLockscreenToAlternateBouncer(.6f),
+ stepFromAlternateBouncer(0f, TransitionState.STARTED),
+ stepFromAlternateBouncer(.4f),
+ stepFromAlternateBouncer(.6f),
+ stepFromAlternateBouncer(1f),
),
testScope,
)
@@ -131,23 +97,13 @@
mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
val alternateBouncerWindowRequired by
collectLastValue(underTest.alternateBouncerWindowRequired)
- givenCanShowAlternateBouncer()
fingerprintPropertyRepository.supportsUdfps()
transitionRepository.sendTransitionSteps(
listOf(
- stepFromLockscreenToDozing(0f, TransitionState.STARTED),
- stepFromLockscreenToDozing(.4f),
- stepFromLockscreenToDozing(.6f),
- stepFromLockscreenToDozing(1f, TransitionState.FINISHED),
- ),
- testScope,
- )
- assertThat(alternateBouncerWindowRequired).isFalse()
- transitionRepository.sendTransitionSteps(
- listOf(
stepFromDozingToLockscreen(0f, TransitionState.STARTED),
stepFromDozingToLockscreen(.4f),
stepFromDozingToLockscreen(.6f),
+ stepFromDozingToLockscreen(1f),
),
testScope,
)
@@ -160,39 +116,19 @@
mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
val alternateBouncerWindowRequired by
collectLastValue(underTest.alternateBouncerWindowRequired)
- givenCanShowAlternateBouncer()
fingerprintPropertyRepository.supportsRearFps()
transitionRepository.sendTransitionSteps(
listOf(
- stepToLockscreen(0f, TransitionState.STARTED),
- stepToLockscreen(.4f),
- stepToLockscreen(1f, TransitionState.FINISHED),
- ),
- testScope,
- )
- transitionRepository.sendTransitionSteps(
- listOf(
- stepFromLockscreenToAlternateBouncer(0f, TransitionState.STARTED),
- stepFromLockscreenToAlternateBouncer(.4f),
- stepFromLockscreenToAlternateBouncer(.6f),
+ stepFromAlternateBouncer(0f, TransitionState.STARTED),
+ stepFromAlternateBouncer(.4f),
+ stepFromAlternateBouncer(.6f),
+ stepFromAlternateBouncer(1f),
),
testScope,
)
assertThat(alternateBouncerWindowRequired).isFalse()
}
- private fun stepToLockscreen(
- value: Float,
- state: TransitionState = TransitionState.RUNNING
- ): TransitionStep {
- return step(
- from = KeyguardState.GONE,
- to = KeyguardState.LOCKSCREEN,
- value = value,
- transitionState = state,
- )
- }
-
private fun stepFromAlternateBouncer(
value: Float,
state: TransitionState = TransitionState.RUNNING
@@ -205,18 +141,6 @@
)
}
- private fun stepFromLockscreenToAlternateBouncer(
- value: Float,
- state: TransitionState = TransitionState.RUNNING
- ): TransitionStep {
- return step(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.ALTERNATE_BOUNCER,
- value = value,
- transitionState = state,
- )
- }
-
private fun stepFromDozingToLockscreen(
value: Float,
state: TransitionState = TransitionState.RUNNING
@@ -229,18 +153,6 @@
)
}
- private fun stepFromLockscreenToDozing(
- value: Float,
- state: TransitionState = TransitionState.RUNNING
- ): TransitionStep {
- return step(
- from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.DOZING,
- value = value,
- transitionState = state,
- )
- }
-
private fun step(
from: KeyguardState,
to: KeyguardState,
@@ -255,16 +167,4 @@
ownerName = "AlternateBouncerViewModelTest"
)
}
-
- /**
- * Given the alternate bouncer parameters are set so that the alternate bouncer can show, aside
- * from the fingerprint modality.
- */
- private fun givenCanShowAlternateBouncer() {
- kosmos.fakeKeyguardBouncerRepository.setPrimaryShow(false)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
- kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true)
- whenever(kosmos.keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false)
- whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false)
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index bdc5fc3..4f4aac4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -46,8 +46,8 @@
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
-import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTouchHandlingInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
@@ -58,6 +58,7 @@
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.pulsingGestureListener
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -178,7 +179,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
val remoteUserSelectionManager =
@@ -211,8 +211,8 @@
dumpManager = mock(),
userHandle = UserHandle.SYSTEM,
)
- val keyguardLongPressInteractor =
- KeyguardLongPressInteractor(
+ val keyguardTouchHandlingInteractor =
+ KeyguardTouchHandlingInteractor(
appContext = mContext,
scope = testScope.backgroundScope,
transitionInteractor = kosmos.keyguardTransitionInteractor,
@@ -221,6 +221,7 @@
featureFlags = featureFlags,
broadcastDispatcher = broadcastDispatcher,
accessibilityManager = accessibilityManager,
+ pulsingGestureListener = kosmos.pulsingGestureListener,
)
underTest =
KeyguardBottomAreaViewModel(
@@ -246,13 +247,13 @@
),
bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
burnInHelperWrapper = burnInHelperWrapper,
- longPressViewModel =
- KeyguardLongPressViewModel(
- interactor = keyguardLongPressInteractor,
+ keyguardTouchHandlingViewModel =
+ KeyguardTouchHandlingViewModel(
+ interactor = keyguardTouchHandlingInteractor,
),
settingsMenuViewModel =
KeyguardSettingsMenuViewModel(
- interactor = keyguardLongPressInteractor,
+ interactor = keyguardTouchHandlingInteractor,
),
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index e33d75c..9fb1aa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -221,7 +221,6 @@
.thenReturn(FakeSharedPreferences())
},
userTracker = userTracker,
- systemSettings = FakeSettings(),
broadcastDispatcher = fakeBroadcastDispatcher,
)
val remoteUserSelectionManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
index a770722..fbfe41f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
@@ -1799,6 +1799,7 @@
any(),
eq(null),
eq(null),
+ eq(null),
)
verify(activityStarter, never()).postStartActivityDismissingKeyguard(eq(clickIntent), any())
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
index df8eafe..196bbb9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
@@ -49,6 +49,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.NavigationBar;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.shared.recents.utilities.Utilities;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
index 5ed8a11..eae6cdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
@@ -7,6 +7,7 @@
import com.android.systemui.dump.DumpManager
import com.android.systemui.model.SysUiState
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler
+import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.shared.system.TaskStackChangeListeners
@@ -70,6 +71,8 @@
lateinit var mCurrentSysUiState: NavBarHelper.CurrentSysuiState
@Mock
lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ @Mock
+ lateinit var mStatusBarStateController: StatusBarStateController
@Before
fun setup() {
@@ -80,7 +83,7 @@
`when`(mSysUiState.setFlag(anyLong(), anyBoolean())).thenReturn(mSysUiState)
mTaskStackChangeListeners = TaskStackChangeListeners.getTestInstance()
mTaskbarDelegate = TaskbarDelegate(context, mLightBarControllerFactory,
- mStatusBarKeyguardViewManager)
+ mStatusBarKeyguardViewManager, mStatusBarStateController)
mTaskbarDelegate.setDependencies(mCommandQueue, mOverviewProxyService, mNavBarHelper,
mNavigationModeController, mSysUiState, mDumpManager, mAutoHideController,
mLightBarController, mOptionalPip, mBackAnimation, mTaskStackChangeListeners)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java
similarity index 97%
rename from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java
index 85244fd..00e79f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -38,6 +38,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.FakeDisplayTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java
similarity index 93%
rename from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java
index a358c18..e58c8f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doNothing;
@@ -32,7 +32,9 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
import com.android.systemui.recents.OverviewProxyService;
import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
similarity index 97%
rename from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
index 982a269..98ff6c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
@@ -28,7 +28,7 @@
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
import static com.android.systemui.assist.AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS;
-import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
+import static com.android.systemui.navigationbar.views.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.google.common.truth.Truth.assertThat;
@@ -39,7 +39,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -86,10 +86,15 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.NavBarHelper;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.NavBarButtonClickLogger;
+import com.android.systemui.navigationbar.views.buttons.NavbarOrientationTrackingLogger;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java
similarity index 93%
rename from packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java
index fbfd35f..3621ab9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar;
+package com.android.systemui.navigationbar.views;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -32,11 +32,13 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.FakeDisplayTracker;
-import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java
similarity index 86%
rename from packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java
index 841f620..403a883 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static android.view.KeyEvent.ACTION_DOWN;
import static android.view.KeyEvent.ACTION_UP;
@@ -26,12 +26,12 @@
import static android.view.KeyEvent.KEYCODE_HOME;
import static android.view.KeyEvent.KEYCODE_UNKNOWN;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java
index 7eb7c8e..79c4a96 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java
index 6a3c615..7941a68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.navigationbar.buttons;
+package com.android.systemui.navigationbar.views.buttons;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
index 42b81de..c918ed8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
@@ -97,6 +97,7 @@
qsTileLogger,
FakeSystemClock(),
testCoroutineDispatcher,
+ testCoroutineDispatcher,
testScope.backgroundScope,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
index 6e6e311..e1c3911 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
@@ -23,6 +23,7 @@
import android.os.PowerManager
import android.os.Process
import android.os.UserHandle
+import android.os.UserManager
import android.testing.TestableContext
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -108,6 +109,7 @@
@Mock private lateinit var navModeController: NavigationModeController
@Mock private lateinit var statusBarWinController: NotificationShadeWindowController
@Mock private lateinit var userTracker: UserTracker
+ @Mock private lateinit var userManager: UserManager
@Mock private lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var sysuiUnlockAnimationController: KeyguardUnlockAnimationController
@Mock
@@ -199,11 +201,12 @@
}
@Test
- fun connectToOverviewService_primaryUser_expectBindService() {
+ fun connectToOverviewService_primaryUserNoVisibleBgUsersSupported_expectBindService() {
val mockitoSession =
ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
try {
`when`(Process.myUserHandle()).thenReturn(UserHandle.SYSTEM)
+ `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(false)
val spyContext = spy(context)
val ops = createOverviewProxyService(spyContext)
ops.startConnectionToCurrentUser()
@@ -214,11 +217,46 @@
}
@Test
- fun connectToOverviewService_nonPrimaryUser_expectNoBindService() {
+ fun connectToOverviewService_nonPrimaryUserNoVisibleBgUsersSupported_expectNoBindService() {
val mockitoSession =
ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
try {
`when`(Process.myUserHandle()).thenReturn(UserHandle.of(12345))
+ `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(false)
+ val spyContext = spy(context)
+ val ops = createOverviewProxyService(spyContext)
+ ops.startConnectionToCurrentUser()
+ verify(spyContext, times(0)).bindServiceAsUser(any(), any(), anyInt(), any())
+ } finally {
+ mockitoSession.finishMocking()
+ }
+ }
+
+ @Test
+ fun connectToOverviewService_nonPrimaryBgUserVisibleBgUsersSupported_expectBindService() {
+ val mockitoSession =
+ ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
+ try {
+ `when`(Process.myUserHandle()).thenReturn(UserHandle.of(12345))
+ `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(true)
+ `when`(userManager.isUserForeground()).thenReturn(false)
+ val spyContext = spy(context)
+ val ops = createOverviewProxyService(spyContext)
+ ops.startConnectionToCurrentUser()
+ verify(spyContext, atLeast(1)).bindServiceAsUser(any(), any(), anyInt(), any())
+ } finally {
+ mockitoSession.finishMocking()
+ }
+ }
+
+ @Test
+ fun connectToOverviewService_nonPrimaryFgUserVisibleBgUsersSupported_expectNoBindService() {
+ val mockitoSession =
+ ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
+ try {
+ `when`(Process.myUserHandle()).thenReturn(UserHandle.of(12345))
+ `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(true)
+ `when`(userManager.isUserForeground()).thenReturn(true)
val spyContext = spy(context)
val ops = createOverviewProxyService(spyContext)
ops.startConnectionToCurrentUser()
@@ -242,6 +280,7 @@
sysUiState,
mock(),
userTracker,
+ userManager,
wakefulnessLifecycle,
uiEventLogger,
displayTracker,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
index 2981590..9986205 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
@@ -43,6 +43,8 @@
import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
@@ -54,6 +56,7 @@
import android.testing.AndroidTestingRunner;
import android.view.Display;
import android.view.View;
+import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
@@ -99,11 +102,14 @@
private static final int BACKLINKS_TASK_ID = 42;
private static final String BACKLINKS_TASK_APP_NAME = "Backlinks app";
private static final String BACKLINKS_TASK_PACKAGE_NAME = "backlinksTaskPackageName";
+
private static final RootTaskInfo TASK_THAT_SUPPORTS_BACKLINKS =
createTaskInfoForBacklinksTask();
-
private static final AssistContent ASSIST_CONTENT_FOR_BACKLINKS_TASK =
createAssistContentForBacklinksTask();
+ private static final Drawable FAKE_DRAWABLE = new ShapeDrawable();
+
+ private ArgumentCaptor<Integer> mDisplayIdCaptor = ArgumentCaptor.forClass(Integer.class);
@Mock
private AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
@@ -171,6 +177,8 @@
assertThat(((ImageView) mActivity.findViewById(R.id.preview)).getDrawable()).isNotNull();
assertThat(mActivity.findViewById(R.id.backlinks_data).getVisibility())
.isEqualTo(View.GONE);
+ assertThat(mActivity.findViewById(R.id.backlinks_include_data).getVisibility())
+ .isEqualTo(View.GONE);
}
@Test
@@ -214,9 +222,44 @@
@Test
@EnableFlags(Flags.FLAG_APP_CLIPS_BACKLINKS)
public void appClipsLaunched_backlinks_displayed() throws RemoteException {
- // Set up mocking to verify backlinks view is displayed on screen.
- ArgumentCaptor<Integer> displayIdCaptor = ArgumentCaptor.forClass(Integer.class);
- when(mAtmService.getAllRootTaskInfosOnDisplay(displayIdCaptor.capture()))
+ setUpMocksForBacklinks();
+
+ launchActivity();
+ waitForIdleSync();
+
+ assertThat(mDisplayIdCaptor.getValue()).isEqualTo(mActivity.getDisplayId());
+ TextView backlinksData = mActivity.findViewById(R.id.backlinks_data);
+ assertThat(backlinksData.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(backlinksData.getText().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
+ assertThat(backlinksData.getCompoundDrawablesRelative()[0]).isEqualTo(FAKE_DRAWABLE);
+
+ CheckBox backlinksIncludeData = mActivity.findViewById(R.id.backlinks_include_data);
+ assertThat(backlinksIncludeData.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(backlinksIncludeData.getText().toString())
+ .isEqualTo(mActivity.getString(R.string.backlinks_include_link));
+ assertThat(backlinksIncludeData.isChecked()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_APP_CLIPS_BACKLINKS)
+ public void appClipsLaunched_backlinks_doNotIncludeLink() throws RemoteException {
+ setUpMocksForBacklinks();
+
+ launchActivity();
+ waitForIdleSync();
+ CheckBox backlinksIncludeData = mActivity.findViewById(R.id.backlinks_include_data);
+ runOnMainThread(() -> backlinksIncludeData.performClick());
+ waitForIdleSync();
+
+ assertThat(backlinksIncludeData.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(backlinksIncludeData.isChecked()).isFalse();
+
+ TextView backlinksData = mActivity.findViewById(R.id.backlinks_data);
+ assertThat(backlinksData.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ private void setUpMocksForBacklinks() throws RemoteException {
+ when(mAtmService.getAllRootTaskInfosOnDisplay(mDisplayIdCaptor.capture()))
.thenReturn(List.of(TASK_THAT_SUPPORTS_BACKLINKS));
doAnswer(invocation -> {
AssistContentRequester.Callback callback = invocation.getArgument(1);
@@ -226,15 +269,7 @@
when(mPackageManager
.resolveActivity(any(Intent.class), anyInt()))
.thenReturn(createBacklinksTaskResolveInfo());
-
- launchActivity();
- waitForIdleSync();
-
- assertThat(displayIdCaptor.getValue()).isEqualTo(mActivity.getDisplayId());
- TextView backlinksData = mActivity.findViewById(R.id.backlinks_data);
- assertThat(backlinksData.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(backlinksData.getText().toString()).isEqualTo(
- mActivity.getString(R.string.backlinks_string, BACKLINKS_TASK_APP_NAME));
+ when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
}
private void launchActivity() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
index 6733ead..809fb3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
@@ -26,6 +26,7 @@
import static com.android.internal.infra.AndroidFuture.completedFuture;
import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_TRIGGERED;
+import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CLIP_DATA;
import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI;
import static com.google.common.truth.Truth.assertThat;
@@ -37,6 +38,7 @@
import static org.mockito.Mockito.when;
import android.app.Activity;
+import android.content.ClipData;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -81,6 +83,7 @@
private static final String TEST_URI_STRING = "www.test-uri.com";
private static final Uri TEST_URI = Uri.parse(TEST_URI_STRING);
+ private static final ClipData TEST_CLIP_DATA = ClipData.newRawUri("Test backlinks", TEST_URI);
private static final int TEST_UID = 42;
private static final String TEST_CALLING_PACKAGE = "test-calling-package";
@@ -238,6 +241,7 @@
Bundle bundle = new Bundle();
bundle.putParcelable(EXTRA_SCREENSHOT_URI, TEST_URI);
bundle.putInt(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE, CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
+ bundle.putParcelable(EXTRA_CLIP_DATA, TEST_CLIP_DATA);
activity.getResultReceiverForTest().send(Activity.RESULT_OK, bundle);
waitForIdleSync();
@@ -245,7 +249,10 @@
assertThat(actualResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
assertThat(getStatusCodeExtra(actualResult.getResultData()))
.isEqualTo(CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
- assertThat(actualResult.getResultData().getData()).isEqualTo(TEST_URI);
+
+ Intent resultData = actualResult.getResultData();
+ assertThat(resultData.getData()).isEqualTo(TEST_URI);
+ assertThat(resultData.getClipData()).isEqualTo(TEST_CLIP_DATA);
assertThat(mActivityRule.getActivity().isFinishing()).isTrue();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
index dcb75d1..baf1357 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
@@ -111,6 +111,7 @@
.thenReturn(List.of(createTaskInfoForBacklinksTask()));
when(mPackageManager.resolveActivity(mPackageManagerIntentCaptor.capture(), anyInt()))
.thenReturn(createBacklinksTaskResolveInfo());
+ when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
mViewModel = new AppClipsViewModel.Factory(mAppClipsCrossProcessHelper, mImageExporter,
mAtmService, mAssistContentRequester, mPackageManager,
@@ -202,12 +203,14 @@
assertThat(queriedIntent.getData()).isEqualTo(expectedUri);
assertThat(queriedIntent.getAction()).isEqualTo(ACTION_VIEW);
- ClipData result = mViewModel.getBacklinksLiveData().getValue();
- ClipDescription resultDescription = result.getDescription();
+ InternalBacklinksData result = mViewModel.getBacklinksLiveData().getValue();
+ assertThat(result.getAppIcon()).isEqualTo(FAKE_DRAWABLE);
+ ClipData clipData = result.getClipData();
+ ClipDescription resultDescription = clipData.getDescription();
assertThat(resultDescription.getLabel().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
assertThat(resultDescription.getMimeType(0)).isEqualTo(MIMETYPE_TEXT_URILIST);
- assertThat(result.getItemCount()).isEqualTo(1);
- assertThat(result.getItemAt(0).getUri()).isEqualTo(expectedUri);
+ assertThat(clipData.getItemCount()).isEqualTo(1);
+ assertThat(clipData.getItemAt(0).getUri()).isEqualTo(expectedUri);
}
@Test
@@ -245,12 +248,14 @@
Intent queriedIntent = mPackageManagerIntentCaptor.getValue();
assertThat(queriedIntent.getPackage()).isEqualTo(expectedIntent.getPackage());
- ClipData result = mViewModel.getBacklinksLiveData().getValue();
- ClipDescription resultDescription = result.getDescription();
+ InternalBacklinksData result = mViewModel.getBacklinksLiveData().getValue();
+ assertThat(result.getAppIcon()).isEqualTo(FAKE_DRAWABLE);
+ ClipData clipData = result.getClipData();
+ ClipDescription resultDescription = clipData.getDescription();
assertThat(resultDescription.getLabel().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
assertThat(resultDescription.getMimeType(0)).isEqualTo(MIMETYPE_TEXT_INTENT);
- assertThat(result.getItemCount()).isEqualTo(1);
- assertThat(result.getItemAt(0).getIntent()).isEqualTo(expectedIntent);
+ assertThat(clipData.getItemCount()).isEqualTo(1);
+ assertThat(clipData.getItemAt(0).getIntent()).isEqualTo(expectedIntent);
}
@Test
@@ -330,6 +335,7 @@
private void resetPackageManagerMockingForUsingFallbackBacklinks() {
reset(mPackageManager);
+ when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
// First the logic queries whether a package has a launcher activity, this should
// resolve otherwise the logic filters out the task.
@@ -340,14 +346,17 @@
}
private void verifyMainLauncherBacklinksIntent() {
- ClipData result = mViewModel.getBacklinksLiveData().getValue();
- assertThat(result.getItemCount()).isEqualTo(1);
+ InternalBacklinksData result = mViewModel.getBacklinksLiveData().getValue();
+ assertThat(result.getAppIcon()).isEqualTo(FAKE_DRAWABLE);
- ClipDescription resultDescription = result.getDescription();
+ ClipData clipData = result.getClipData();
+ assertThat(clipData.getItemCount()).isEqualTo(1);
+
+ ClipDescription resultDescription = clipData.getDescription();
assertThat(resultDescription.getLabel().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
assertThat(resultDescription.getMimeType(0)).isEqualTo(MIMETYPE_TEXT_INTENT);
- Intent actualBacklinksIntent = result.getItemAt(0).getIntent();
+ Intent actualBacklinksIntent = clipData.getItemAt(0).getIntent();
assertThat(actualBacklinksIntent.getPackage()).isEqualTo(BACKLINKS_TASK_PACKAGE_NAME);
assertThat(actualBacklinksIntent.getAction()).isEqualTo(ACTION_MAIN);
assertThat(actualBacklinksIntent.getCategories()).containsExactly(CATEGORY_LAUNCHER);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 88b832d..e7ca091 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -111,7 +111,7 @@
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel;
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
@@ -334,7 +334,7 @@
@Mock protected PrimaryBouncerToGoneTransitionViewModel
mPrimaryBouncerToGoneTransitionViewModel;
@Mock protected KeyguardTransitionInteractor mKeyguardTransitionInteractor;
- @Mock protected KeyguardLongPressViewModel mKeyuardLongPressViewModel;
+ @Mock protected KeyguardTouchHandlingViewModel mKeyuardTouchHandlingViewModel;
@Mock protected AlternateBouncerInteractor mAlternateBouncerInteractor;
@Mock protected MotionEvent mDownMotionEvent;
@Mock protected CoroutineDispatcher mMainDispatcher;
@@ -464,6 +464,7 @@
() -> mShadeInteractor,
() -> mKosmos.getDeviceUnlockedInteractor(),
() -> mKosmos.getSceneInteractor(),
+ () -> mKosmos.getSceneContainerOcclusionInteractor(),
() -> mKosmos.getKeyguardClockInteractor());
KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
@@ -621,6 +622,7 @@
() -> mShadeInteractor,
() -> mKosmos.getDeviceUnlockedInteractor(),
() -> mKosmos.getSceneInteractor(),
+ () -> mKosmos.getSceneContainerOcclusionInteractor(),
() -> mKosmos.getKeyguardClockInteractor()),
mKeyguardBypassController,
mDozeParameters,
@@ -753,7 +755,7 @@
mMainDispatcher,
mKeyguardTransitionInteractor,
mDumpManager,
- mKeyuardLongPressViewModel,
+ mKeyuardTouchHandlingViewModel,
mKeyguardInteractor,
mActivityStarter,
mSharedNotificationContainerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index c3e810e..1a6b420 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -69,7 +69,27 @@
}
@Test
- fun chip_inCall_isShownAsTimer() =
+ fun chip_inCall_zeroStartTime_isShownAsIconOnly() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+ }
+
+ @Test
+ fun chip_inCall_negativeStartTime_isShownAsIconOnly() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = -2, intent = null))
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+ }
+
+ @Test
+ fun chip_inCall_positiveStartTime_isShownAsTimer() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -97,7 +117,7 @@
}
@Test
- fun chip_iconIsPhone() =
+ fun chip_positiveStartTime_iconIsPhone() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -105,10 +125,25 @@
assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
.isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
+ .isNotNull()
}
@Test
- fun chip_colorsAreThemed() =
+ fun chip_zeroStartTime_iconIsPhone() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+ assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
+ .isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
+ .isNotNull()
+ }
+
+ @Test
+ fun chip_positiveStartTime_colorsAreThemed() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -119,6 +154,17 @@
}
@Test
+ fun chip_zeroStartTime_colorsAreThemed() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+ assertThat((latest as OngoingActivityChipModel.Shown).colors)
+ .isEqualTo(ColorsModel.Themed)
+ }
+
+ @Test
fun chip_resetsCorrectly() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -157,7 +203,7 @@
}
@Test
- fun chip_inCall_validIntent_clickListenerLaunchesIntent() =
+ fun chip_inCall_positiveStartTime_validIntent_clickListenerLaunchesIntent() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -170,4 +216,19 @@
verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(intent, null)
}
+
+ @Test
+ fun chip_inCall_zeroStartTime_validIntent_clickListenerLaunchesIntent() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ val intent = mock<PendingIntent>()
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = intent))
+ val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
+ assertThat(clickListener).isNotNull()
+
+ clickListener!!.onClick(chipView)
+
+ verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(intent, null)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index bde668e..74b6ae2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -104,6 +104,7 @@
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
val icon = (latest as OngoingActivityChipModel.Shown).icon
assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ assertThat(icon.contentDescription).isNotNull()
}
@Test
@@ -117,6 +118,7 @@
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
val icon = (latest as OngoingActivityChipModel.Shown).icon
assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ assertThat(icon.contentDescription).isNotNull()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index 8e8b082..0a06cc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -143,6 +143,7 @@
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
val icon = (latest as OngoingActivityChipModel.Shown).icon
assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenrecord)
+ assertThat(icon.contentDescription).isNotNull()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
index 2e5f7f5..3028d00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -129,6 +129,7 @@
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
val icon = (latest as OngoingActivityChipModel.Shown).icon
assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ assertThat(icon.contentDescription).isNotNull()
}
@Test
@@ -142,6 +143,7 @@
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
val icon = (latest as OngoingActivityChipModel.Shown).icon
assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ assertThat(icon.contentDescription).isNotNull()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
index e984200..a7f36c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
@@ -20,6 +20,7 @@
import android.app.Notification.CATEGORY_EVENT
import android.app.Notification.CATEGORY_REMINDER
import android.app.NotificationManager
+import android.content.pm.PackageManager.PERMISSION_DENIED
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -28,11 +29,16 @@
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE
-import java.util.Optional
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.anyString
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
+import org.mockito.kotlin.whenever
+import java.util.Optional
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -58,7 +64,9 @@
avalancheProvider,
systemSettings,
packageManager,
- Optional.of(bubbles)
+ Optional.of(bubbles),
+ context,
+ notificationManager
)
}
@@ -87,12 +95,60 @@
// because avalanche code is based on the suppression refactor.
@Test
+ fun testAvalancheFilter_suppress_hasNotSeenEdu_showEduHun() {
+ setAllowedEmergencyPkg(false)
+ whenever(avalancheProvider.timeoutMs).thenReturn(20)
+ whenever(avalancheProvider.startTime).thenReturn(whenAgo(10))
+
+ val avalancheSuppressor = AvalancheSuppressor(
+ avalancheProvider, systemClock, systemSettings, packageManager,
+ uiEventLogger, context, notificationManager
+ )
+ avalancheSuppressor.hasSeenEdu = false
+
+ withFilter(avalancheSuppressor) {
+ ensurePeekState()
+ assertShouldNotHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ whenMs = whenAgo(5)
+ }
+ )
+ }
+ verify(notificationManager, times(1)).notify(anyInt(), any())
+ }
+
+ @Test
+ fun testAvalancheFilter_suppress_hasSeenEduHun_doNotShowEduHun() {
+ setAllowedEmergencyPkg(false)
+ whenever(avalancheProvider.timeoutMs).thenReturn(20)
+ whenever(avalancheProvider.startTime).thenReturn(whenAgo(10))
+
+ val avalancheSuppressor = AvalancheSuppressor(
+ avalancheProvider, systemClock, systemSettings, packageManager,
+ uiEventLogger, context, notificationManager
+ )
+ avalancheSuppressor.hasSeenEdu = true
+
+ withFilter(avalancheSuppressor) {
+ ensurePeekState()
+ assertShouldNotHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ whenMs = whenAgo(5)
+ }
+ )
+ }
+ verify(notificationManager, times(0)).notify(anyInt(), any())
+ }
+
+ @Test
fun testAvalancheFilter_duringAvalanche_allowConversationFromAfterEvent() {
avalancheProvider.startTime = whenAgo(10)
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldHeadsUp(
@@ -112,7 +168,7 @@
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldNotHeadsUp(
@@ -132,7 +188,7 @@
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldHeadsUp(
@@ -150,7 +206,7 @@
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldHeadsUp(
@@ -168,7 +224,7 @@
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldHeadsUp(
@@ -186,7 +242,7 @@
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldHeadsUp(
@@ -204,7 +260,7 @@
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
assertFsiNotSuppressed()
}
@@ -216,7 +272,7 @@
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldHeadsUp(
@@ -228,20 +284,24 @@
}
}
- @Test
- fun testAvalancheFilter_duringAvalanche_allowEmergency() {
- avalancheProvider.startTime = whenAgo(10)
-
+ private fun setAllowedEmergencyPkg(allow: Boolean) {
`when`(
packageManager.checkPermission(
org.mockito.Mockito.eq(permission.RECEIVE_EMERGENCY_BROADCAST),
anyString()
)
- ).thenReturn(PERMISSION_GRANTED)
+ ).thenReturn(if (allow) PERMISSION_GRANTED else PERMISSION_DENIED)
+ }
+
+ @Test
+ fun testAvalancheFilter_duringAvalanche_allowEmergency() {
+ avalancheProvider.startTime = whenAgo(10)
+
+ setAllowedEmergencyPkg(true)
withFilter(
AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
- uiEventLogger)
+ uiEventLogger, context, notificationManager)
) {
ensurePeekState()
assertShouldHeadsUp(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
index a457405..378705a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
@@ -31,6 +31,7 @@
import android.app.Notification.GROUP_ALERT_SUMMARY
import android.app.Notification.VISIBILITY_PRIVATE
import android.app.NotificationChannel
+import android.app.NotificationManager
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.IMPORTANCE_LOW
@@ -133,7 +134,7 @@
protected val bubbles: Bubbles = mock()
lateinit var systemSettings: SystemSettings
protected val packageManager: PackageManager = mock()
-
+ protected val notificationManager: NotificationManager = mock()
protected abstract val provider: VisualInterruptionDecisionProvider
private val neverSuppresses = object : NotificationInterruptSuppressor {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
index 01e638b..f4cebd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
@@ -15,6 +15,8 @@
*/
package com.android.systemui.statusbar.notification.interruption
+import android.app.NotificationManager
+import android.content.Context
import android.content.pm.PackageManager
import android.hardware.display.AmbientDisplayConfiguration
import android.os.Handler
@@ -58,6 +60,8 @@
systemSettings: SystemSettings,
packageManager: PackageManager,
bubbles: Optional<Bubbles>,
+ context: Context,
+ notificationManager: NotificationManager
): VisualInterruptionDecisionProvider {
return if (VisualInterruptionRefactor.isEnabled) {
VisualInterruptionDecisionProviderImpl(
@@ -79,7 +83,9 @@
avalancheProvider,
systemSettings,
packageManager,
- bubbles
+ bubbles,
+ context,
+ notificationManager
)
} else {
NotificationInterruptStateProviderWrapper(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 164a06e..e8349b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -862,11 +862,12 @@
@Test
@EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
- public void isExpanded_systemExpandedTrueForHeadsUp_notExpanded() throws Exception {
+ public void isExpanded_HUNsystemExpandedTrueForPinned_notExpanded() throws Exception {
// GIVEN
final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
row.setOnKeyguard(false);
row.setSystemExpanded(true);
+ row.setPinned(true);
row.setHeadsUp(true);
// THEN
@@ -875,12 +876,27 @@
@Test
@EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
- public void isExpanded_systemExpandedTrueForHeadsUpDisappearRunning_notExpanded()
+ public void isExpanded_HUNsystemExpandedTrueForNotPinned_expanded() throws Exception {
+ // GIVEN
+ final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+ row.setOnKeyguard(false);
+ row.setSystemExpanded(true);
+ row.setPinned(false);
+ row.setHeadsUp(true);
+
+ // THEN
+ assertThat(row.isExpanded()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+ public void isExpanded_HUNDisappearingsystemExpandedTrueForPinned_notExpanded()
throws Exception {
// GIVEN
final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
row.setOnKeyguard(false);
row.setSystemExpanded(true);
+ row.setPinned(true);
row.setHeadsUpAnimatingAway(true);
// THEN
@@ -889,6 +905,21 @@
@Test
@EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+ public void isExpanded_HUNDisappearingsystemExpandedTrueForNotPinned_expanded()
+ throws Exception {
+ // GIVEN
+ final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+ row.setOnKeyguard(false);
+ row.setSystemExpanded(true);
+ row.setPinned(false);
+ row.setHeadsUpAnimatingAway(true);
+
+ // THEN
+ assertThat(row.isExpanded()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
public void isExpanded_userExpandedTrueForHeadsUp_expanded() throws Exception {
// GIVEN
final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index ce2491b..1060b62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -53,6 +53,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.ExpandHelper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
@@ -99,6 +100,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback;
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -135,6 +137,8 @@
@Mock private NotificationVisibilityProvider mVisibilityProvider;
@Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
@Mock private HeadsUpManager mHeadsUpManager;
+ @Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback;
+ @Mock private Provider<IStatusBarService> mStatusBarService;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private TunerService mTunerService;
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@@ -973,6 +977,8 @@
when(mNotificationStackScrollLayout.getViewTreeObserver())
.thenReturn(viewTreeObserver);
when(mNotificationStackScrollLayout.getContext()).thenReturn(getContext());
+ when(mNotificationStackScrollLayout.getHeadsUpCallback()).thenReturn(mHeadsUpCallback);
+ when(mHeadsUpCallback.getContext()).thenReturn(getContext());
mController = new NotificationStackScrollLayoutController(
mNotificationStackScrollLayout,
true,
@@ -981,6 +987,7 @@
mVisibilityProvider,
mNotificationWakeUpCoordinator,
mHeadsUpManager,
+ mStatusBarService,
mNotificationRoundnessManager,
mTunerService,
mDeviceProvisionedController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 1eb33ce..d2540a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -53,6 +53,7 @@
import android.app.ActivityManager;
import android.app.IWallpaperManager;
+import android.app.NotificationManager;
import android.app.WallpaperManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
@@ -339,6 +340,7 @@
@Mock private KeyboardShortcuts mKeyboardShortcuts;
@Mock private KeyboardShortcutListSearch mKeyboardShortcutListSearch;
@Mock private PackageManager mPackageManager;
+ @Mock private NotificationManager mNotificationManager;
@Mock private GlanceableHubContainerController mGlanceableHubContainerController;
@Mock private EmergencyGestureIntentFactory mEmergencyGestureIntentFactory;
@@ -399,7 +401,9 @@
mAvalancheProvider,
mSystemSettings,
mPackageManager,
- Optional.of(mBubbles));
+ Optional.of(mBubbles),
+ mContext,
+ mNotificationManager);
mVisualInterruptionDecisionProvider.start();
mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 53e643e..0cb28cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -52,28 +52,17 @@
import com.android.keyguard.CarrierTextController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.keyguard.TestScopeProvider;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.battery.BatteryMeterViewController;
-import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository;
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
import com.android.systemui.flags.DisableSceneContainer;
import com.android.systemui.flags.EnableSceneContainer;
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeViewStateProvider;
-import com.android.systemui.shade.data.repository.FakeShadeRepository;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.data.repository.FakeKeyguardStatusBarRepository;
-import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
import com.android.systemui.statusbar.phone.ui.TintedIconManager;
@@ -82,14 +71,11 @@
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
-import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel;
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
-import kotlinx.coroutines.test.TestScope;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -150,11 +136,7 @@
private KeyguardStatusBarViewController mController;
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
- private final TestScope mTestScope = TestScopeProvider.getTestScope();
- private final FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository();
private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
- private KeyguardInteractor mKeyguardInteractor;
- private KeyguardStatusBarViewModel mViewModel;
@Before
public void setup() throws Exception {
@@ -163,28 +145,6 @@
MockitoAnnotations.initMocks(this);
when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);
- KeyguardTransitionInteractor keyguardTransitionInteractor =
- mKosmos.getKeyguardTransitionInteractor();
- mKeyguardInteractor = new KeyguardInteractor(
- mKeyguardRepository,
- mCommandQueue,
- PowerInteractorFactory.create().getPowerInteractor(),
- new FakeKeyguardBouncerRepository(),
- new ConfigurationInteractor(new FakeConfigurationRepository()),
- new FakeShadeRepository(),
- keyguardTransitionInteractor,
- () -> mKosmos.getSceneInteractor(),
- () -> mKosmos.getFromGoneTransitionInteractor(),
- () -> mKosmos.getFromLockscreenTransitionInteractor(),
- () -> mKosmos.getSharedNotificationContainerInteractor(),
- mTestScope);
- mViewModel =
- new KeyguardStatusBarViewModel(
- mTestScope.getBackgroundScope(),
- mKosmos.getHeadsUpNotificationInteractor(),
- mKeyguardInteractor,
- new KeyguardStatusBarInteractor(new FakeKeyguardStatusBarRepository()),
- mBatteryController);
allowTestableLooperAsMainThread();
TestableLooper.get(this).runWithLooper(() -> {
@@ -212,7 +172,7 @@
mKeyguardStateController,
mKeyguardBypassController,
mKeyguardUpdateMonitor,
- mViewModel,
+ mKosmos.getKeyguardStatusBarViewModel(),
mBiometricUnlockController,
mStatusBarStateController,
mStatusBarContentInsetsProvider,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
index a27073c..88ec18d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
@@ -18,7 +18,7 @@
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
import static junit.framework.Assert.assertTrue;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
index c4568a9..318656b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
@@ -21,12 +21,12 @@
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSLUCENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
new file mode 100644
index 0000000..230ddf9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.testKosmos
+import com.android.systemui.util.kotlin.getValue
+import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalCoroutinesApi::class)
+class StatusBarTouchableRegionManagerTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val sceneRepository = kosmos.sceneContainerRepository
+
+ private val underTest by Lazy { kosmos.statusBarTouchableRegionManager }
+
+ @Test
+ @EnableSceneContainer
+ fun entireScreenTouchable_sceneContainerEnabled_isRemoteUserInteractionOngoing() =
+ testScope.runTest {
+ sceneRepository.setTransitionState(
+ flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Gone))
+ )
+ runCurrent()
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+ sceneRepository.isRemoteUserInteractionOngoing.value = true
+ runCurrent()
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isTrue()
+
+ sceneRepository.isRemoteUserInteractionOngoing.value = false
+ runCurrent()
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun entireScreenTouchable_sceneContainerDisabled_isRemoteUserInteractionOngoing() =
+ testScope.runTest {
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+ sceneRepository.isRemoteUserInteractionOngoing.value = true
+ runCurrent()
+
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun entireScreenTouchable_sceneContainerEnabled_isIdleOnGone() =
+ testScope.runTest {
+ sceneRepository.setTransitionState(
+ flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Gone))
+ )
+ runCurrent()
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+ sceneRepository.setTransitionState(
+ flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Shade))
+ )
+ runCurrent()
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isTrue()
+
+ sceneRepository.setTransitionState(
+ flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Gone))
+ )
+ runCurrent()
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun entireScreenTouchable_sceneContainerDisabled_isIdleOnGone() =
+ testScope.runTest {
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+ sceneRepository.setTransitionState(
+ flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Shade))
+ )
+ runCurrent()
+
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index ee27cea..01540e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -49,6 +49,8 @@
import com.android.systemui.animation.AnimatorTestRule;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.DisableSceneContainer;
+import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogcatEchoTracker;
import com.android.systemui.plugins.DarkIconDispatcher;
@@ -302,6 +304,7 @@
}
@Test
+ @DisableSceneContainer
public void disable_shadeOpenAndShouldHide_everythingHidden() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -318,6 +321,7 @@
}
@Test
+ @DisableSceneContainer
public void disable_shadeOpenButNotShouldHide_everythingShown() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -335,6 +339,7 @@
/** Regression test for b/279790651. */
@Test
+ @DisableSceneContainer
public void disable_shadeOpenAndShouldHide_thenShadeNotOpenAndDozingUpdate_everythingShown() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -376,6 +381,7 @@
}
@Test
+ @DisableSceneContainer
public void disable_isTransitioningToOccluded_everythingHidden() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -390,6 +396,7 @@
}
@Test
+ @DisableSceneContainer
public void disable_wasTransitioningToOccluded_transitionFinished_everythingShown() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -674,6 +681,80 @@
}
@Test
+ @EnableSceneContainer
+ public void isHomeStatusBarAllowedByScene_false_everythingHidden() {
+ resumeAndGetFragment();
+
+ mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);
+
+ // THEN all views are hidden
+ assertEquals(View.GONE, getClockView().getVisibility());
+ assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
+ assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
+ }
+
+ @Test
+ @EnableSceneContainer
+ public void isHomeStatusBarAllowedByScene_true_everythingShown() {
+ resumeAndGetFragment();
+
+ mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(true);
+
+ // THEN all views are shown
+ assertEquals(View.VISIBLE, getClockView().getVisibility());
+ assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
+ assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+ }
+
+ @Test
+ @EnableSceneContainer
+ public void disable_isHomeStatusBarAllowedBySceneFalse_disableValuesIgnored() {
+ CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+
+ // WHEN the scene doesn't allow the status bar
+ mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);
+
+ // BUT the disable flags want to show the status bar
+ fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
+
+ // THEN all views are hidden (the disable flags aren't respected)
+ assertEquals(View.GONE, getClockView().getVisibility());
+ assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
+ assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
+ }
+
+ @Test
+ @EnableSceneContainer
+ public void disable_isHomeStatusBarAllowedBySceneTrue_disableValuesUsed() {
+ CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+
+ // WHEN the scene does allow the status bar
+ mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(true);
+
+ // AND the disable flags want to hide the clock
+ fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_CLOCK, 0, false);
+
+ // THEN all views are shown except the clock (the disable flags are used)
+ assertEquals(View.GONE, getClockView().getVisibility());
+ assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
+ assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+ }
+
+ @Test
+ @DisableSceneContainer
+ public void isHomeStatusBarAllowedByScene_sceneContainerDisabled_valueNotUsed() {
+ resumeAndGetFragment();
+
+ // Even if the scene says to hide the home status bar
+ mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);
+
+ // The value isn't used because the scene container flag is disabled, so all views are shown
+ assertEquals(View.VISIBLE, getClockView().getVisibility());
+ assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
+ assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+ }
+
+ @Test
public void disable_isDozing_clockAndSystemInfoVisible() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
when(mStatusBarStateController.isDozing()).thenReturn(true);
@@ -758,6 +839,7 @@
}
@Test
+ @DisableSceneContainer
public void testStatusBarIcons_hiddenThroughoutCameraLaunch() {
final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -779,6 +861,7 @@
}
@Test
+ @DisableSceneContainer
public void testStatusBarIcons_hiddenThroughoutLockscreenToDreamTransition() {
final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
index b4c6106..94159bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
@@ -24,6 +24,7 @@
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
@@ -36,6 +37,10 @@
import com.android.systemui.log.assertLogsWtf
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.screenRecordRepository
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
@@ -84,6 +89,8 @@
kosmos.lightsOutInteractor,
kosmos.activeNotificationsInteractor,
kosmos.keyguardTransitionInteractor,
+ kosmos.sceneInteractor,
+ kosmos.sceneContainerOcclusionInteractor,
kosmos.ongoingActivityChipsViewModel,
kosmos.applicationCoroutineScope,
)
@@ -426,6 +433,68 @@
assertIsShareToAppChip(latest)
}
+ @Test
+ fun isHomeStatusBarAllowedByScene_sceneLockscreen_notOccluded_false() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null)
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ fun isHomeStatusBarAllowedByScene_sceneLockscreen_occluded_true() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, taskInfo = null)
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ fun isHomeStatusBarAllowedByScene_sceneBouncer_false() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ fun isHomeStatusBarAllowedByScene_sceneCommunal_false() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Communal)
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ fun isHomeStatusBarAllowedByScene_sceneShade_false() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
+
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ fun isHomeStatusBarAllowedByScene_sceneGone_true() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
+
+ assertThat(latest).isTrue()
+ }
+
private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) =
ActiveNotificationsStore.Builder()
.apply { notifications.forEach(::addIndividualNotif) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
index b66eed0..d3f1125 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
@@ -31,6 +31,8 @@
override val ongoingActivityChip: MutableStateFlow<OngoingActivityChipModel> =
MutableStateFlow(OngoingActivityChipModel.Hidden)
+ override val isHomeStatusBarAllowedByScene = MutableStateFlow(false)
+
override fun areNotificationsLightsOut(displayId: Int): Flow<Boolean> = areNotificationLightsOut
fun setNotificationLightsOut(lightsOut: Boolean) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 70afbd8..ffe7750 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -247,7 +247,7 @@
ExpandableNotificationRow row = helper.createRow();
RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
- view.addOnVisibilityChangedListener(null);
+ view.setOnVisibilityChangedListener(null);
view.setVisibility(View.INVISIBLE);
view.setVisibility(View.VISIBLE);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index d88289d..ef4e734 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
@@ -26,8 +26,10 @@
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor
import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
@@ -85,6 +87,7 @@
KeyguardStatusBarViewModel(
testScope.backgroundScope,
headsUpNotificationInteractor,
+ kosmos.sceneInteractor,
keyguardInteractor,
keyguardStatusBarInteractor,
batteryController,
@@ -95,7 +98,7 @@
fun isVisible_dozing_false() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
keyguardRepository.setIsDozing(true)
@@ -103,21 +106,21 @@
}
@Test
- fun isVisible_statusBarStateShade_false() =
+ fun isVisible_sceneShade_false() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.SHADE)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
assertThat(latest).isFalse()
}
@Test
- fun isVisible_statusBarStateShadeLocked_false() =
+ fun isVisible_sceneBouncer_false() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
assertThat(latest).isFalse()
}
@@ -130,7 +133,7 @@
// WHEN HUN displayed on the bypass lock screen
headsUpRepository.setNotifications(FakeHeadsUpRowRepository("key 0", isPinned = true))
keyguardTransitionRepository.emitInitialStepsFromOff(KeyguardState.LOCKSCREEN)
- keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
faceAuthRepository.isBypassEnabled.value = true
// THEN KeyguardStatusBar is NOT visible to make space for HeadsUpStatusBar
@@ -138,11 +141,11 @@
}
@Test
- fun isVisible_statusBarStateKeyguard_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
+ fun isVisible_sceneLockscreen_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
testScope.runTest {
val latest by collectLastValue(underTest.isVisible)
- keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
keyguardRepository.setIsDozing(false)
assertThat(latest).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
index 5b9db4b..5603ff0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -31,8 +31,8 @@
import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEventLogger
import com.android.systemui.InstanceIdSequenceFake
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.eq
@@ -109,6 +109,14 @@
}
@Test
+ fun updateBatteryState_capacityNaN_cancelsNotification() {
+ stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(Float.NaN))
+
+ verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
+ verifyNoMoreInteractions(notificationManager)
+ }
+
+ @Test
fun updateBatteryState_capacityBelowThreshold_notifies() {
stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
index 97688d5..ef2d4ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
@@ -29,10 +29,16 @@
import com.android.systemui.unfold.util.TestFoldStateProvider
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
+import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+/**
+ * This test class tests [PhysicsBasedUnfoldTransitionProgressProvider] in a more E2E
+ * fashion, it uses real handler thread and timings, so it might be perceptible to more flakiness
+ * compared to the other unit tests that do not perform real multithreaded interactions.
+ */
@RunWith(AndroidJUnit4::class)
@SmallTest
class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() {
@@ -44,8 +50,8 @@
mock<UnfoldFrameCallbackScheduler.Factory>().apply {
whenever(create()).then { UnfoldFrameCallbackScheduler() }
}
- private val mockBgHandler = mock<Handler>()
- private val fakeHandler = Handler(HandlerThread("UnfoldBg").apply { start() }.looper)
+ private val handlerThread = HandlerThread("UnfoldBg").apply { start() }
+ private val bgHandler = Handler(handlerThread.looper)
@Before
fun setUp() {
@@ -54,20 +60,26 @@
context,
schedulerFactory,
foldStateProvider = foldStateProvider,
- progressHandler = fakeHandler
+ progressHandler = bgHandler
)
progressProvider.addCallback(listener)
}
+ @After
+ fun after() {
+ handlerThread.quit()
+ }
+
@Test
fun testUnfold_emitsIncreasingTransitionEvents() {
runOnProgressThreadWithInterval(
{ foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
{ foldStateProvider.sendHingeAngleUpdate(10f) },
- { foldStateProvider.sendUnfoldedScreenAvailable() },
- { foldStateProvider.sendHingeAngleUpdate(90f) },
- { foldStateProvider.sendHingeAngleUpdate(180f) },
- { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
+ { foldStateProvider.sendUnfoldedScreenAvailable() }
+ )
+ sendHingeAngleAndEnsureAnimationUpdate(90f, 120f, 180f)
+ runOnProgressThreadWithInterval(
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) }
)
with(listener.ensureTransitionFinished()) {
@@ -91,7 +103,7 @@
}
@Test
- fun testUnfold_screenAvailableOnlyAfterFullUnfold_emitsIncreasingTransitionEvents() {
+ fun testUnfold_screenAvailableOnlyAfterFullUnfold_finishesWithUnfoldEvent() {
runOnProgressThreadWithInterval(
{ foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
{ foldStateProvider.sendHingeAngleUpdate(10f) },
@@ -102,7 +114,6 @@
)
with(listener.ensureTransitionFinished()) {
- assertIncreasingProgress()
assertFinishedWithUnfold()
}
}
@@ -111,9 +122,9 @@
fun testFold_emitsDecreasingTransitionEvents() {
runOnProgressThreadWithInterval(
{ foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_CLOSING) },
- { foldStateProvider.sendHingeAngleUpdate(170f) },
- { foldStateProvider.sendHingeAngleUpdate(90f) },
- { foldStateProvider.sendHingeAngleUpdate(10f) },
+ )
+ sendHingeAngleAndEnsureAnimationUpdate(170f, 90f, 10f)
+ runOnProgressThreadWithInterval(
{ foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) },
)
@@ -127,9 +138,9 @@
fun testUnfoldAndStopUnfolding_finishesTheUnfoldTransition() {
runOnProgressThreadWithInterval(
{ foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
- { foldStateProvider.sendUnfoldedScreenAvailable() },
- { foldStateProvider.sendHingeAngleUpdate(10f) },
- { foldStateProvider.sendHingeAngleUpdate(90f) },
+ { foldStateProvider.sendUnfoldedScreenAvailable() })
+ sendHingeAngleAndEnsureAnimationUpdate(10f, 50f, 90f)
+ runOnProgressThreadWithInterval(
{ foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN) },
)
@@ -159,12 +170,22 @@
with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() }
}
+ private fun sendHingeAngleAndEnsureAnimationUpdate(vararg angles: Float) {
+ angles.forEach { angle ->
+ listener.waitForProgressChangeAfter {
+ bgHandler.post {
+ foldStateProvider.sendHingeAngleUpdate(angle)
+ }
+ }
+ }
+ }
+
private fun runOnProgressThreadWithInterval(
vararg blocks: () -> Unit,
intervalMillis: Long = 60,
) {
blocks.forEach {
- fakeHandler.post(it)
+ bgHandler.post(it)
Thread.sleep(intervalMillis)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
index bbc96f70..6e8bf85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
@@ -68,6 +68,24 @@
return recordings.first()
}
+ /**
+ * Number of progress event for the currently running transition
+ * Returns null if there is no currently running transition
+ */
+ val currentTransitionProgressEventCount: Int?
+ get() = currentRecording?.progressHistory?.size
+
+ /**
+ * Runs [block] and ensures that there was at least once onTransitionProgress event after that
+ */
+ fun waitForProgressChangeAfter(block: () -> Unit) {
+ val eventCount = currentTransitionProgressEventCount
+ block()
+ waitForCondition {
+ currentTransitionProgressEventCount != eventCount
+ }
+ }
+
fun assertStarted() {
assertWithMessage("Transition didn't start").that(currentRecording).isNotNull()
}
@@ -86,7 +104,7 @@
}
class UnfoldTransitionRecording {
- private val progressHistory: MutableList<Float> = arrayListOf()
+ val progressHistory: MutableList<Float> = arrayListOf()
private var finishingInvocations: Int = 0
fun addProgress(progress: Float) {
@@ -142,6 +160,6 @@
}
private companion object {
- private const val MIN_ANIMATION_EVENTS = 5
+ private const val MIN_ANIMATION_EVENTS = 3
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
index ef8d51a..dd791e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
@@ -27,6 +27,11 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Test
@@ -41,12 +46,16 @@
@TestableLooper.RunWithLooper
class SettingsProxyTest : SysuiTestCase() {
+ private val testDispatcher = StandardTestDispatcher()
+
private lateinit var mSettings: SettingsProxy
private lateinit var mContentObserver: ContentObserver
+ private lateinit var testScope: TestScope
@Before
fun setUp() {
- mSettings = FakeSettingsProxy()
+ testScope = TestScope(testDispatcher)
+ mSettings = FakeSettingsProxy(testDispatcher)
mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
}
@@ -58,6 +67,23 @@
}
@Test
+ fun registerContentObserverSuspend_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputString_success() {
+ mSettings.registerContentObserverAsync(TEST_SETTING, mContentObserver)
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
+ }
+
+ @Test
fun registerContentObserver_inputString_notifyForDescendants_true() {
mSettings.registerContentObserverSync(
TEST_SETTING,
@@ -69,6 +95,31 @@
}
@Test
+ fun registerContentObserverSuspend_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserver(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputString_notifyForDescendants_true() {
+ mSettings.registerContentObserverAsync(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+ }
+
+ @Test
fun registerContentObserver_inputUri_success() {
mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
verify(mSettings.getContentResolver())
@@ -76,6 +127,23 @@
}
@Test
+ fun registerContentObserverSuspend_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_success() {
+ mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+ }
+ }
+
+ @Test
fun registerContentObserver_inputUri_notifyForDescendants_true() {
mSettings.registerContentObserverSync(
TEST_SETTING_URI,
@@ -87,12 +155,52 @@
}
@Test
- fun unregisterContentObserver() {
+ fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserver(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_notifyForDescendants_true() {
+ mSettings.registerContentObserverAsync(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver
+ )
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+ }
+ }
+
+ @Test
+ fun unregisterContentObserverSync() {
mSettings.unregisterContentObserverSync(mContentObserver)
verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
}
@Test
+ fun unregisterContentObserverSuspend_inputString_success() =
+ testScope.runTest {
+ mSettings.unregisterContentObserver(mContentObserver)
+ verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+ }
+
+ @Test
+ fun unregisterContentObserverAsync_inputString_success() {
+ mSettings.unregisterContentObserverAsync(mContentObserver)
+ testScope.launch {
+ verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+ }
+ }
+
+ @Test
fun getString_keyPresent_returnValidValue() {
mSettings.putString(TEST_SETTING, "test")
assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -199,13 +307,16 @@
assertThat(mSettings.getFloat(TEST_SETTING, 2.5F)).isEqualTo(2.5F)
}
- private class FakeSettingsProxy : SettingsProxy {
+ private class FakeSettingsProxy(val testDispatcher: CoroutineDispatcher) : SettingsProxy {
private val mContentResolver = mock(ContentResolver::class.java)
private val settingToValueMap: MutableMap<String, String> = mutableMapOf()
override fun getContentResolver() = mContentResolver
+ override val backgroundDispatcher: CoroutineDispatcher
+ get() = testDispatcher
+
override fun getUriFor(name: String) =
Uri.parse(StringBuilder().append("content://settings/").append(name).toString())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
index c08ca7d..e3e20c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
@@ -30,6 +30,11 @@
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserTracker
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Test
@@ -45,8 +50,10 @@
class UserSettingsProxyTest : SysuiTestCase() {
private var mUserTracker = FakeUserTracker()
- private var mSettings: UserSettingsProxy = FakeUserSettingsProxy(mUserTracker)
+ private val testDispatcher = StandardTestDispatcher()
+ private var mSettings: UserSettingsProxy = FakeUserSettingsProxy(mUserTracker, testDispatcher)
private var mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
+ private lateinit var testScope: TestScope
@Before
fun setUp() {
@@ -54,6 +61,7 @@
listOf(UserInfo(MAIN_USER_ID, "main", UserInfo.FLAG_MAIN)),
selectedUserIndex = 0
)
+ testScope = TestScope(testDispatcher)
}
@Test
@@ -73,6 +81,41 @@
}
@Test
+ fun registerContentObserverForUserSuspend_inputString_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserAsync_inputString_success() {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+ }
+
+ @Test
fun registerContentObserverForUser_inputString_notifyForDescendants_true() {
mSettings.registerContentObserverForUserSync(
TEST_SETTING,
@@ -90,6 +133,45 @@
}
@Test
+ fun registerContentObserverForUserSuspend_inputString_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(
+ true,
+ ),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserAsync_inputString_notifyForDescendants_true() {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(true),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+ }
+
+ @Test
fun registerContentObserverForUser_inputUri_success() {
mSettings.registerContentObserverForUserSync(
TEST_SETTING_URI,
@@ -106,6 +188,41 @@
}
@Test
+ fun registerContentObserverForUserSuspend_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING_URI,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserAsync_inputUri_success() {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING_URI,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+ }
+
+ @Test
fun registerContentObserverForUser_inputUri_notifyForDescendants_true() {
mSettings.registerContentObserverForUserSync(
TEST_SETTING_URI,
@@ -123,6 +240,45 @@
}
@Test
+ fun registerContentObserverForUserSuspend_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserverForUser(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(
+ true,
+ ),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+
+ @Test
+ fun registerContentObserverForUserAsync_inputUri_notifyForDescendants_true() {
+ mSettings.registerContentObserverForUserAsync(
+ TEST_SETTING_URI,
+ notifyForDescendants = true,
+ mContentObserver,
+ mUserTracker.userId
+ )
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(true),
+ eq(mContentObserver),
+ eq(MAIN_USER_ID)
+ )
+ }
+ }
+
+ @Test
fun registerContentObserver_inputUri_success() {
mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
verify(mSettings.getContentResolver())
@@ -130,6 +286,33 @@
}
@Test
+ fun registerContentObserverSuspend_inputUri_success() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_success() {
+ mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+ }
+
+ @Test
fun registerContentObserver_inputUri_notifyForDescendants_true() {
mSettings.registerContentObserverSync(
TEST_SETTING_URI,
@@ -141,6 +324,33 @@
}
@Test
+ fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+ testScope.runTest {
+ mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+
+ @Test
+ fun registerContentObserverAsync_inputUri_notifyForDescendants_true() {
+ mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+ testScope.launch {
+ verify(mSettings.getContentResolver())
+ .registerContentObserver(
+ eq(TEST_SETTING_URI),
+ eq(false),
+ eq(mContentObserver),
+ eq(0)
+ )
+ }
+ }
+
+ @Test
fun getString_keyPresent_returnValidValue() {
mSettings.putString(TEST_SETTING, "test")
assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -300,7 +510,10 @@
*
* This class uses a mock of [ContentResolver] to test the [ContentObserver] registration APIs.
*/
- private class FakeUserSettingsProxy(override val userTracker: UserTracker) : UserSettingsProxy {
+ private class FakeUserSettingsProxy(
+ override val userTracker: UserTracker,
+ val testDispatcher: CoroutineDispatcher
+ ) : UserSettingsProxy {
private val mContentResolver = mock(ContentResolver::class.java)
private val userIdToSettingsValueMap: MutableMap<Int, MutableMap<String, String>> =
@@ -311,6 +524,9 @@
override fun getUriFor(name: String) =
Uri.parse(StringBuilder().append(URI_PREFIX).append(name).toString())
+ override val backgroundDispatcher: CoroutineDispatcher
+ get() = testDispatcher
+
override fun getStringForUser(name: String, userHandle: Int) =
userIdToSettingsValueMap[userHandle]?.get(name) ?: ""
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index c5fbc39..dc7a2c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -59,6 +59,7 @@
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -473,7 +474,9 @@
mock(AvalancheProvider.class),
mock(SystemSettings.class),
mock(PackageManager.class),
- Optional.of(mock(Bubbles.class))
+ Optional.of(mock(Bubbles.class)),
+ mContext,
+ mock(NotificationManager.class)
);
interruptionDecisionProvider.start();
diff --git a/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt b/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt
new file mode 100644
index 0000000..3f3c30f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 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 android.hardware.display
+
+import android.content.applicationContext
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.ambientDisplayConfiguration by Fixture {
+ FakeAmbientDisplayConfiguration(applicationContext)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index 78d8abe..a124b34 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -43,7 +43,7 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.systemui.broadcast.FakeBroadcastDispatcher;
import com.android.systemui.flags.SceneContainerRule;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
index 5db9d31..9dae44d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
@@ -16,7 +16,6 @@
package com.android.systemui
import android.app.ActivityManager
-import android.app.DreamManager
import android.app.admin.DevicePolicyManager
import android.app.trust.TrustManager
import android.os.UserManager
@@ -33,7 +32,6 @@
import com.android.systemui.biometrics.AuthController
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
-import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.ScreenLifecycle
@@ -95,7 +93,6 @@
@get:Provides val demoModeController: DemoModeController = mock(),
@get:Provides val deviceProvisionedController: DeviceProvisionedController = mock(),
@get:Provides val dozeParameters: DozeParameters = mock(),
- @get:Provides val dreamManager: DreamManager = mock(),
@get:Provides val dumpManager: DumpManager = mock(),
@get:Provides val headsUpManager: HeadsUpManager = mock(),
@get:Provides val guestResumeSessionReceiver: GuestResumeSessionReceiver = mock(),
@@ -133,7 +130,6 @@
@get:Provides val systemUIDialogManager: SystemUIDialogManager = mock(),
@get:Provides val deviceEntryIconTransitions: Set<DeviceEntryIconTransition> = emptySet(),
@get:Provides val communalInteractor: CommunalInteractor = mock(),
- @get:Provides val communalSceneInteractor: CommunalSceneInteractor = mock(),
@get:Provides val sceneLogger: SceneLogger = mock(),
@get:Provides val trustManager: TrustManager = mock(),
@get:Provides val primaryBouncerInteractor: PrimaryBouncerInteractor = mock(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
index 045bd5d..25e7729 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
@@ -30,10 +30,16 @@
private val _isBypassEnabled = MutableStateFlow(false)
override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled
+ var userPresentCount = 0
+
override suspend fun isLockscreenEnabled(): Boolean {
return isLockscreenEnabled
}
+ override suspend fun reportUserPresent() {
+ userPresentCount++
+ }
+
fun setLockscreenEnabled(isLockscreenEnabled: Boolean) {
this.isLockscreenEnabled = isLockscreenEnabled
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index f51036f..385a6dc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -19,10 +19,12 @@
import android.content.applicationContext
import android.content.res.mainResources
import android.hardware.input.fakeInputManager
+import android.view.windowManager
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperCategoriesRepository
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperTestHelper
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperCategoriesInteractor
@@ -37,10 +39,10 @@
import com.android.systemui.model.sysUiState
import com.android.systemui.settings.displayTracker
-val Kosmos.shortcutHelperSystemShortcutsSource by
+var Kosmos.shortcutHelperSystemShortcutsSource: KeyboardShortcutGroupsSource by
Kosmos.Fixture { SystemShortcutsSource(mainResources) }
-val Kosmos.shortcutHelperMultiTaskingShortcutsSource by
+var Kosmos.shortcutHelperMultiTaskingShortcutsSource: KeyboardShortcutGroupsSource by
Kosmos.Fixture { MultitaskingShortcutsSource(mainResources) }
val Kosmos.shortcutHelperStateRepository by
@@ -59,6 +61,8 @@
ShortcutHelperCategoriesRepository(
shortcutHelperSystemShortcutsSource,
shortcutHelperMultiTaskingShortcutsSource,
+ windowManager,
+ shortcutHelperStateRepository
)
}
@@ -68,7 +72,8 @@
shortcutHelperStateRepository,
applicationContext,
broadcastDispatcher,
- fakeCommandQueue
+ fakeCommandQueue,
+ windowManager
)
}
@@ -83,12 +88,7 @@
}
val Kosmos.shortcutHelperCategoriesInteractor by
- Kosmos.Fixture {
- ShortcutHelperCategoriesInteractor(
- shortcutHelperStateRepository,
- shortcutHelperCategoriesRepository
- )
- }
+ Kosmos.Fixture { ShortcutHelperCategoriesInteractor(shortcutHelperCategoriesRepository) }
val Kosmos.shortcutHelperViewModel by
Kosmos.Fixture { ShortcutHelperViewModel(testDispatcher, shortcutHelperStateInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
index 36608ff..40510db 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
@@ -18,20 +18,45 @@
import android.content.Context
import android.content.Intent
+import android.view.KeyboardShortcutGroup
+import android.view.WindowManager
+import android.view.WindowManager.KeyboardShortcutsReceiver
import com.android.systemui.broadcast.FakeBroadcastDispatcher
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
class ShortcutHelperTestHelper(
repo: ShortcutHelperStateRepository,
private val context: Context,
private val fakeBroadcastDispatcher: FakeBroadcastDispatcher,
private val fakeCommandQueue: FakeCommandQueue,
+ windowManager: WindowManager
) {
+ companion object {
+ const val DEFAULT_DEVICE_ID = 123
+ }
+
+ private var imeShortcuts: List<KeyboardShortcutGroup> = emptyList()
+
init {
+ whenever(windowManager.requestImeKeyboardShortcuts(any(), any())).thenAnswer {
+ val keyboardShortcutReceiver = it.getArgument<KeyboardShortcutsReceiver>(0)
+ keyboardShortcutReceiver.onKeyboardShortcutsReceived(imeShortcuts)
+ return@thenAnswer Unit
+ }
repo.start()
}
+ /**
+ * Use this method to set what ime shortcuts should be returned from windowManager in tests. By
+ * default windowManager.requestImeKeyboardShortcuts will return emptyList. See init block.
+ */
+ fun setImeShortcuts(imeShortcuts: List<KeyboardShortcutGroup>) {
+ this.imeShortcuts = imeShortcuts
+ }
+
fun hideThroughCloseSystemDialogs() {
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
context,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt
new file mode 100644
index 0000000..e4c17a0
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+
+class FakeKeyboardShortcutGroupsSource : KeyboardShortcutGroupsSource {
+
+ private var groups = listOf<KeyboardShortcutGroup>()
+
+ override fun shortcutGroups(): List<KeyboardShortcutGroup> = groups
+
+ fun setGroups(groups: List<KeyboardShortcutGroup>) {
+ this.groups = groups
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/DismissCallbackRegistryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/DismissCallbackRegistryKosmos.kt
new file mode 100644
index 0000000..b12f947
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/DismissCallbackRegistryKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard
+
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.dismissCallbackRegistry by Fixture { DismissCallbackRegistry(fakeExecutor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
index 744b127..edf77a0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
@@ -16,9 +16,7 @@
package com.android.systemui.keyguard.domain.interactor
-import android.service.dream.dreamManager
import com.android.systemui.communal.domain.interactor.communalInteractor
-import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
@@ -37,10 +35,8 @@
mainDispatcher = testDispatcher,
keyguardInteractor = keyguardInteractor,
communalInteractor = communalInteractor,
- communalSceneInteractor = communalSceneInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
deviceEntryRepository = deviceEntryRepository,
- dreamManager = dreamManager
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
index c06f833..73799b6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
@@ -24,10 +24,11 @@
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.shade.pulsingGestureListener
-val Kosmos.keyguardLongPressInteractor by
+val Kosmos.keyguardTouchHandlingInteractor by
Kosmos.Fixture {
- KeyguardLongPressInteractor(
+ KeyguardTouchHandlingInteractor(
appContext = applicationContext,
scope = applicationCoroutineScope,
transitionInteractor = keyguardTransitionInteractor,
@@ -36,5 +37,6 @@
featureFlags = featureFlagsClassic,
broadcastDispatcher = broadcastDispatcher,
accessibilityManager = accessibilityManagerWrapper,
+ pulsingGestureListener = pulsingGestureListener,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
index 3c62b44..b5e6f75 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
@@ -23,7 +23,6 @@
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.notificationIconContainerAlwaysOnDisplayViewModel
-import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
import com.android.systemui.statusbar.ui.systemBarUtilsProxy
val Kosmos.keyguardClockViewModel by
@@ -32,7 +31,6 @@
keyguardClockInteractor = keyguardClockInteractor,
applicationScope = applicationCoroutineScope,
aodNotificationIconViewModel = notificationIconContainerAlwaysOnDisplayViewModel,
- notifsKeyguardInteractor = notificationsKeyguardInteractor,
shadeInteractor = shadeInteractor,
systemBarUtils = systemBarUtilsProxy,
configurationInteractor = configurationInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt
index 3c9846a..281d7b0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt
@@ -16,12 +16,12 @@
package com.android.systemui.keyguard.ui.viewmodel
-import com.android.systemui.keyguard.domain.interactor.keyguardLongPressInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTouchHandlingInteractor
import com.android.systemui.kosmos.Kosmos
-val Kosmos.keyguardLongPressViewModel by
+val Kosmos.keyguardTouchHandlingViewModel by
Kosmos.Fixture {
- KeyguardLongPressViewModel(
- interactor = keyguardLongPressInteractor,
+ KeyguardTouchHandlingViewModel(
+ interactor = keyguardTouchHandlingInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
index 30a4f21..24e47b0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
@@ -30,7 +30,7 @@
clockInteractor = keyguardClockInteractor,
interactor = keyguardBlueprintInteractor,
authController = authController,
- longPress = keyguardLongPressViewModel,
+ touchHandling = keyguardTouchHandlingViewModel,
shadeInteractor = shadeInteractor,
applicationScope = applicationCoroutineScope,
unfoldTransitionInteractor = unfoldTransitionInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index 31cdbc7..0666820 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -50,6 +50,7 @@
import com.android.systemui.plugins.statusbar.statusBarStateController
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.scrimStartable
import com.android.systemui.scene.sceneContainerConfig
@@ -67,6 +68,7 @@
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.wifiInteractor
import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvisioningRepository
import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
+import com.android.systemui.statusbar.ui.viewmodel.keyguardStatusBarViewModel
import com.android.systemui.util.time.systemClock
import com.android.systemui.volume.domain.interactor.volumeDialogInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -101,6 +103,7 @@
val keyguardInteractor by lazy { kosmos.keyguardInteractor }
val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor }
+ val keyguardStatusBarViewModel by lazy { kosmos.keyguardStatusBarViewModel }
val powerRepository by lazy { kosmos.fakePowerRepository }
val clock by lazy { kosmos.systemClock }
val mobileConnectionsRepository by lazy { kosmos.fakeMobileConnectionsRepository }
@@ -142,4 +145,5 @@
val ongoingActivityChipsViewModel by lazy { kosmos.ongoingActivityChipsViewModel }
val scrimController by lazy { kosmos.scrimController }
val scrimStartable by lazy { kosmos.scrimStartable }
+ val sceneContainerOcclusionInteractor by lazy { kosmos.sceneContainerOcclusionInteractor }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
index ec56327..f9f8d23 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
@@ -22,6 +22,7 @@
import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.StatusBarStateControllerImpl
@@ -38,6 +39,7 @@
{ shadeInteractor },
{ deviceUnlockedInteractor },
{ sceneInteractor },
+ { sceneContainerOcclusionInteractor },
{ keyguardClockInteractor },
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt
new file mode 100644
index 0000000..da55e21
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.data.repository
+
+import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+
+val Kosmos.quickQuickSettingsRowRepository by
+ Kosmos.Fixture {
+ testCase.context.orCreateTestableResources
+ QuickQuickSettingsRowRepository(testCase.context.resources, configurationRepository)
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt
new file mode 100644
index 0000000..3fcbc8d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.data.repository.quickQuickSettingsRowRepository
+
+val Kosmos.quickQuickSettingsRowInteractor by
+ Kosmos.Fixture { QuickQuickSettingsRowInteractor(quickQuickSettingsRowRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
new file mode 100644
index 0000000..40d2624
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.qs.panels.domain.interactor.quickQuickSettingsRowInteractor
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+
+val Kosmos.quickQuickSettingsViewModel by
+ Kosmos.Fixture {
+ QuickQuickSettingsViewModel(
+ currentTilesInteractor,
+ fixedColumnsSizeViewModel,
+ quickQuickSettingsRowInteractor,
+ iconTilesViewModel,
+ applicationCoroutineScope,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
index 419e781..dceb8bf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
@@ -33,7 +33,6 @@
import com.android.systemui.util.mockito.whenever
import javax.inject.Provider
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
var Kosmos.newFactoryTileMap by Kosmos.Fixture { emptyMap<String, Provider<QSTileViewModel>>() }
@@ -50,7 +49,7 @@
instanceIdSequenceFake.newInstanceId(),
)
object : QSTileViewModel {
- override val state: SharedFlow<QSTileState> =
+ override val state: StateFlow<QSTileState?> =
MutableStateFlow(QSTileState.build({ null }, tileSpec.spec) {})
override val config: QSTileConfig = config
override val isAvailable: StateFlow<Boolean> = MutableStateFlow(true)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
index dcfcce7..537be4f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
@@ -69,6 +69,7 @@
qsTileLogger,
systemClock,
testDispatcher,
+ testDispatcher,
testScope.backgroundScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
new file mode 100644
index 0000000..779634d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.ui.viewmodel
+
+import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModel
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
+
+val Kosmos.quickSettingsContainerViewModel by
+ Kosmos.Fixture {
+ QuickSettingsContainerViewModel(
+ brightnessSliderViewModel,
+ tileGridViewModel,
+ editModeViewModel,
+ quickQuickSettingsViewModel,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
similarity index 62%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
index 8adb26f..c56c56c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
@@ -14,24 +14,19 @@
* limitations under the License.
*/
-package com.android.systemui.shade.ui.viewmodel
+package com.android.systemui.qs.ui.viewmodel
-import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
-import com.android.systemui.qs.ui.adapter.qsSceneAdapter
-import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneViewModel
+import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.ui.viewmodel.overlayShadeViewModel
val Kosmos.quickSettingsShadeSceneViewModel: QuickSettingsShadeSceneViewModel by
Kosmos.Fixture {
QuickSettingsShadeSceneViewModel(
- overlayShadeViewModel = overlayShadeViewModel,
- brightnessSliderViewModel = brightnessSliderViewModel,
- tileGridViewModel = tileGridViewModel,
- editModeViewModel = editModeViewModel,
- qsSceneAdapter = qsSceneAdapter,
shadeInteractor = shadeInteractor,
+ overlayShadeViewModel = overlayShadeViewModel,
+ quickSettingsContainerViewModel = quickSettingsContainerViewModel,
+ applicationScope = applicationCoroutineScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
index 641a757..2f17ca8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
@@ -18,8 +18,11 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -30,6 +33,25 @@
private val mutableTransitionState =
MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(Scenes.Lockscreen))
+suspend fun Kosmos.setTransition(
+ sceneTransition: ObservableTransitionState,
+ stateTransition: TransitionStep? = null,
+ scope: TestScope = testScope,
+ repository: SceneContainerRepository = sceneContainerRepository
+) {
+ if (SceneContainerFlag.isEnabled) {
+ setSceneTransition(sceneTransition, scope, repository)
+ } else {
+ if (stateTransition == null) throw IllegalArgumentException("No transitionStep provided")
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = stateTransition.from,
+ to = stateTransition.to,
+ testScope = scope,
+ throughTransitionState = stateTransition.transitionState
+ )
+ }
+}
+
fun Kosmos.setSceneTransition(
transition: ObservableTransitionState,
scope: TestScope = testScope,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
index a661ab6..03a42bc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
@@ -25,8 +25,10 @@
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.keyguard.dismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
@@ -53,6 +55,7 @@
deviceUnlockedInteractor = deviceUnlockedInteractor,
bouncerInteractor = bouncerInteractor,
keyguardInteractor = keyguardInteractor,
+ keyguardTransitionInteractor = keyguardTransitionInteractor,
sysUiState = sysUiState,
displayId = displayTracker.defaultDisplayId,
sceneLogger = sceneLogger,
@@ -73,5 +76,6 @@
shadeSessionStorage = shadeSessionStorage,
windowMgrLockscreenVisInteractor = windowManagerLockscreenVisibilityInteractor,
keyguardEnabledInteractor = keyguardEnabledInteractor,
+ dismissCallbackRegistry = dismissCallbackRegistry,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt
new file mode 100644
index 0000000..4fc2228
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import android.hardware.display.ambientDisplayConfiguration
+import com.android.systemui.classifier.falsingManager
+import com.android.systemui.dock.dockManager
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.keyguard.domain.interactor.dozeInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.plugins.statusbar.statusBarStateController
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.settings.userTracker
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.pulsingGestureListener by Fixture {
+ PulsingGestureListener(
+ falsingManager = falsingManager,
+ dockManager = dockManager,
+ powerInteractor = powerInteractor,
+ ambientDisplayConfiguration = ambientDisplayConfiguration,
+ statusBarStateController = statusBarStateController,
+ shadeLogger = mock(),
+ dozeInteractor = dozeInteractor,
+ userTracker = userTracker,
+ tunerService = mock(),
+ dumpManager = dumpManager,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
index b85858d..79b80bc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
@@ -27,7 +27,9 @@
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.panelExpansionInteractor
import com.android.systemui.shade.transition.ScrimShadeTransitionController
+import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
import com.android.systemui.statusbar.policy.splitShadeStateController
+import com.android.systemui.statusbar.pulseExpansionHandler
import com.android.systemui.util.mockito.mock
@Deprecated("ShadeExpansionStateManager is deprecated. Remove your dependency on it instead.")
@@ -45,5 +47,7 @@
sceneInteractorProvider = { sceneInteractor },
panelExpansionInteractorProvider = { panelExpansionInteractor },
shadeExpansionStateManager = shadeExpansionStateManager,
+ pulseExpansionHandler = pulseExpansionHandler,
+ nsslc = notificationStackScrollLayoutController,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelKosmos.kt
new file mode 100644
index 0000000..989c3a5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelKosmos.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
+import com.android.systemui.qs.footerActionsController
+import com.android.systemui.qs.footerActionsViewModelFactory
+import com.android.systemui.qs.ui.adapter.qsSceneAdapter
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
+
+val Kosmos.shadeSceneViewModel: ShadeSceneViewModel by
+ Kosmos.Fixture {
+ ShadeSceneViewModel(
+ applicationScope = applicationCoroutineScope,
+ shadeHeaderViewModel = shadeHeaderViewModel,
+ qsSceneAdapter = qsSceneAdapter,
+ brightnessMirrorViewModel = brightnessMirrorViewModel,
+ mediaCarouselInteractor = mediaCarouselInteractor,
+ shadeInteractor = shadeInteractor,
+ footerActionsViewModelFactory = footerActionsViewModelFactory,
+ footerActionsController = footerActionsController,
+ sceneInteractor = sceneInteractor,
+ unfoldTransitionInteractor = unfoldTransitionInteractor,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
index 7bf77e5..492e87b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
@@ -30,7 +30,12 @@
override val topHeadsUpRow: Flow<HeadsUpRowRepository?> = MutableStateFlow(null)
override val activeHeadsUpRows: MutableStateFlow<Set<HeadsUpRowRepository>> =
MutableStateFlow(emptySet())
+
override fun setHeadsUpAnimatingAway(animatingAway: Boolean) {
isHeadsUpAnimatingAway.value = animatingAway
}
+
+ override fun snooze() {
+ // do nothing
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
index f0eea38..afb8acb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
@@ -18,10 +18,11 @@
import com.android.systemui.dump.dumpManager
import com.android.systemui.flags.featureFlagsClassic
-import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.ui.viewmodel.shadeSceneViewModel
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
val Kosmos.notificationsPlaceholderViewModel by Fixture {
@@ -29,7 +30,8 @@
dumpManager = dumpManager,
interactor = notificationStackAppearanceInteractor,
shadeInteractor = shadeInteractor,
+ shadeSceneViewModel = shadeSceneViewModel,
+ headsUpNotificationInteractor = headsUpNotificationInteractor,
featureFlags = featureFlagsClassic,
- keyguardInteractor = keyguardInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
new file mode 100644
index 0000000..8785256
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.content.applicationContext
+import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
+import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notificationShadeWindowController
+import com.android.systemui.statusbar.policy.configurationController
+import com.android.systemui.statusbar.policy.headsUpManager
+import com.android.systemui.util.kotlin.JavaAdapter
+import com.android.systemui.util.mockito.mock
+import org.mockito.Mockito.mock
+
+var Kosmos.statusBarTouchableRegionManager by
+ Kosmos.Fixture {
+ StatusBarTouchableRegionManager(
+ applicationContext,
+ notificationShadeWindowController,
+ configurationController,
+ headsUpManager,
+ shadeInteractor,
+ { sceneInteractor },
+ JavaAdapter(testScope.backgroundScope),
+ mock<UnlockedScreenOffAnimationController>(),
+ primaryBouncerInteractor,
+ alternateBouncerInteractor,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt
new file mode 100644
index 0000000..ea79edc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
+import com.android.systemui.statusbar.policy.batteryController
+
+val Kosmos.keyguardStatusBarViewModel: KeyguardStatusBarViewModel by
+ Kosmos.Fixture {
+ KeyguardStatusBarViewModel(
+ applicationCoroutineScope,
+ headsUpNotificationInteractor,
+ sceneInteractor,
+ keyguardInteractor,
+ keyguardStatusBarInteractor,
+ batteryController,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
index 3a70cdf..476b7d8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
@@ -16,12 +16,16 @@
package com.android.systemui.util.settings;
+import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
+import kotlinx.coroutines.CoroutineDispatcher;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -30,10 +34,16 @@
public class FakeGlobalSettings implements GlobalSettings {
private final Map<String, String> mValues = new HashMap<>();
private final Map<String, List<ContentObserver>> mContentObserversAllUsers = new HashMap<>();
+ private final CoroutineDispatcher mDispatcher;
public static final Uri CONTENT_URI = Uri.parse("content://settings/fake_global");
public FakeGlobalSettings() {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
+ }
+
+ public FakeGlobalSettings(CoroutineDispatcher dispatcher) {
+ mDispatcher = dispatcher;
}
@Override
@@ -44,6 +54,11 @@
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mDispatcher;
+ }
+
+ @Override
public void registerContentObserverSync(Uri uri, boolean notifyDescendants,
ContentObserver settingsObserver) {
List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
index cd219ec..e35da11 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
@@ -16,6 +16,8 @@
package com.android.systemui.util.settings;
+import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
+
import android.annotation.UserIdInt;
import android.content.ContentResolver;
import android.database.ContentObserver;
@@ -27,6 +29,8 @@
import com.android.systemui.settings.UserTracker;
+import kotlinx.coroutines.CoroutineDispatcher;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -37,19 +41,27 @@
private final Map<SettingsKey, List<ContentObserver>> mContentObservers =
new HashMap<>();
private final Map<String, List<ContentObserver>> mContentObserversAllUsers = new HashMap<>();
+ private final CoroutineDispatcher mDispatcher;
public static final Uri CONTENT_URI = Uri.parse("content://settings/fake");
@UserIdInt
private int mUserId = UserHandle.USER_CURRENT;
public FakeSettings() {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
+ }
+
+ public FakeSettings(CoroutineDispatcher dispatcher) {
+ mDispatcher = dispatcher;
}
public FakeSettings(String initialKey, String initialValue) {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
putString(initialKey, initialValue);
}
public FakeSettings(Map<String, String> initialValues) {
+ mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
for (Map.Entry<String, String> kv : initialValues.entrySet()) {
putString(kv.getKey(), kv.getValue());
}
@@ -66,6 +78,11 @@
}
@Override
+ public CoroutineDispatcher getBackgroundDispatcher() {
+ return mDispatcher;
+ }
+
+ @Override
public void registerContentObserverForUserSync(Uri uri, boolean notifyDescendants,
ContentObserver settingsObserver, int userHandle) {
List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
index b2b19de..e6b52f0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
@@ -20,6 +20,7 @@
import com.android.internal.logging.uiEventLogger
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.volume.domain.interactor.audioVolumeInteractor
+import com.android.systemui.volume.shared.volumePanelLogger
import kotlinx.coroutines.CoroutineScope
val Kosmos.audioStreamSliderViewModelFactory by
@@ -36,6 +37,7 @@
applicationContext,
audioVolumeInteractor,
uiEventLogger,
+ volumePanelLogger,
)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/shared/VolumePanelLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/shared/VolumePanelLoggerKosmos.kt
new file mode 100644
index 0000000..3a7574d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/shared/VolumePanelLoggerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.shared
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.volume.panel.shared.VolumePanelLogger
+
+val Kosmos.volumePanelLogger by Kosmos.Fixture { VolumePanelLogger(logcatLogBuffer()) }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
index fec6ff1..0458f53 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
@@ -28,6 +28,9 @@
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.util.concurrent.CopyOnWriteArrayList
+import java.util.concurrent.atomic.AtomicInteger
+
+private const val INVALID_ROTATION = -1
/**
* Allows to subscribe to rotation changes. Updates are provided for the display associated to
@@ -45,7 +48,7 @@
private val listeners = CopyOnWriteArrayList<RotationListener>()
private val displayListener = RotationDisplayListener()
- private var lastRotation: Int? = null
+ private val lastRotation = AtomicInteger(INVALID_ROTATION)
override fun addCallback(listener: RotationListener) {
bgHandler.post {
@@ -61,7 +64,7 @@
listeners -= listener
if (listeners.isEmpty()) {
unsubscribeToRotation()
- lastRotation = null
+ lastRotation.set(INVALID_ROTATION)
}
}
}
@@ -100,9 +103,8 @@
if (displayId == display.displayId) {
val currentRotation = display.rotation
- if (lastRotation == null || lastRotation != currentRotation) {
+ if (lastRotation.compareAndSet(lastRotation.get(), currentRotation)) {
listeners.forEach { it.onRotationChanged(currentRotation) }
- lastRotation = currentRotation
}
}
} finally {
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index ad216b5..e2eb09f 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -231,6 +231,12 @@
}
filegroup {
+ name: "ravenwood-framework-jarjar-rules",
+ srcs: ["texts/ravenwood-framework-jarjar-rules.txt"],
+ visibility: ["//frameworks/base"],
+}
+
+filegroup {
name: "ravenwood-services-jarjar-rules",
srcs: ["texts/ravenwood-services-jarjar-rules.txt"],
visibility: ["//frameworks/base"],
@@ -268,12 +274,14 @@
src: "scripts/ravenwood-stats-checker.sh",
test_suites: ["general-tests"],
data: [
- ":framework-minus-apex.ravenwood.stats",
- ":framework-minus-apex.ravenwood.apis",
- ":framework-minus-apex.ravenwood.keep_all",
- ":services.core.ravenwood.stats",
- ":services.core.ravenwood.apis",
- ":services.core.ravenwood.keep_all",
+ ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_stats.csv}",
+ ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_apis.csv}",
+ ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_keep_all.txt}",
+ ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_dump.txt}",
+ ":services.core.ravenwood-base{hoststubgen_services.core_stats.csv}",
+ ":services.core.ravenwood-base{hoststubgen_services.core_apis.csv}",
+ ":services.core.ravenwood-base{hoststubgen_services.core_keep_all.txt}",
+ ":services.core.ravenwood-base{hoststubgen_services.core_dump.txt}",
],
}
diff --git a/ravenwood/bivalenttest/Android.bp b/ravenwood/bivalenttest/Android.bp
index 2d94894..06cf08e6 100644
--- a/ravenwood/bivalenttest/Android.bp
+++ b/ravenwood/bivalenttest/Android.bp
@@ -38,6 +38,9 @@
"androidx.annotation_annotation",
"androidx.test.ext.junit",
"androidx.test.rules",
+
+ // To make sure it won't cause VerifyError (b/324063814)
+ "platformprotosnano",
],
srcs: [
"test/**/*.java",
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodBaseContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodBaseContext.java
index 4992c4b..63bcda188 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodBaseContext.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodBaseContext.java
@@ -447,6 +447,14 @@
}
@Override
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ String[] receiverPermissions, int appOp, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ throw notSupported();
+ }
+
+ @Override
public void sendStickyBroadcast(Intent intent) {
throw notSupported();
}
diff --git a/ravenwood/scripts/ravenwood-stats-collector.sh b/ravenwood/scripts/ravenwood-stats-collector.sh
index 43b61a4..36601bd 100755
--- a/ravenwood/scripts/ravenwood-stats-collector.sh
+++ b/ravenwood/scripts/ravenwood-stats-collector.sh
@@ -22,10 +22,12 @@
stats=$out_dir/ravenwood-stats-all.csv
apis=$out_dir/ravenwood-apis-all.csv
keep_all_dir=$out_dir/ravenwood-keep-all/
+dump_dir=$out_dir/ravenwood-dump/
rm -fr $out_dir
mkdir -p $out_dir
mkdir -p $keep_all_dir
+mkdir -p $dump_dir
# Where the input files are.
path=$ANDROID_BUILD_TOP/out/host/linux-x86/testcases/ravenwood-stats-checker/x86_64/
@@ -85,4 +87,8 @@
cp *keep_all.txt $keep_all_dir
echo "Keep all files created at:"
-find $keep_all_dir -type f
\ No newline at end of file
+find $keep_all_dir -type f
+
+cp *dump.txt $dump_dir
+echo "Dump files created at:"
+find $dump_dir -type f
\ No newline at end of file
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index f3172ae..bdc3577 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -274,7 +274,9 @@
android.telephony.ModemActivityInfo
android.telephony.ServiceState
+android.os.connectivity.CellularBatteryStats
android.os.connectivity.WifiActivityEnergyInfo
+android.os.connectivity.WifiBatteryStats
com.android.server.LocalServices
diff --git a/ravenwood/texts/ravenwood-framework-jarjar-rules.txt b/ravenwood/texts/ravenwood-framework-jarjar-rules.txt
new file mode 100644
index 0000000..2eeb904
--- /dev/null
+++ b/ravenwood/texts/ravenwood-framework-jarjar-rules.txt
@@ -0,0 +1,2 @@
+# To avoid VerifyError on nano proto files (b/324063814)
+rule com.**.nano.** devicenano.@0
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index f9196f3..d3efa21 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -610,7 +610,7 @@
}
}
- void notifyAccessibilityButtonClicked(int displayId) {
+ void notifyMagnificationShortcutTriggered(int displayId) {
if (mMagnificationGestureHandler.size() != 0) {
final MagnificationGestureHandler handler = mMagnificationGestureHandler.get(displayId);
if (handler != null) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 1654a8d..32491b7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -47,6 +47,7 @@
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.USER_SHORTCUT_TYPES;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
@@ -849,14 +850,17 @@
userState.mEnabledServices, userState.mUserId);
}
- boolean buttonTargetsChanged = userState.mAccessibilityButtonTargets.removeIf(
+ // Remove any button targets that match any stopped continuous services
+ Set<String> buttonTargets = userState.getShortcutTargetsLocked(SOFTWARE);
+ boolean buttonTargetsChanged = buttonTargets.removeIf(
target -> continuousServicePackages.stream().anyMatch(
pkg -> Objects.equals(target, pkg)));
if (buttonTargetsChanged) {
+ userState.updateShortcutTargetsLocked(buttonTargets, SOFTWARE);
persistColonDelimitedSetToSettingLocked(
- Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+ ShortcutUtils.convertToKey(SOFTWARE),
userState.mUserId,
- userState.mAccessibilityButtonTargets, str -> str);
+ buttonTargets, str -> str);
}
return enabledServicesChanged || buttonTargetsChanged;
@@ -1606,7 +1610,7 @@
}
mMainHandler.sendMessage(obtainMessage(
AccessibilityManagerService::performAccessibilityShortcutInternal, this,
- displayId, UserShortcutType.SOFTWARE, targetName));
+ displayId, SOFTWARE, targetName));
}
/**
@@ -2217,10 +2221,10 @@
}
}
- private void sendAccessibilityButtonToInputFilter(int displayId) {
+ private void notifyMagnificationShortcutTriggered(int displayId) {
synchronized (mLock) {
if (mHasInputFilter && mInputFilter != null) {
- mInputFilter.notifyAccessibilityButtonClicked(displayId);
+ mInputFilter.notifyMagnificationShortcutTriggered(displayId);
}
}
}
@@ -3081,9 +3085,10 @@
scheduleUpdateInputFilter(userState);
updateRelevantEventsLocked(userState);
scheduleUpdateClientsIfNeededLocked(userState, forceUpdate);
- updateAccessibilityShortcutKeyTargetsLocked(userState);
- updateAccessibilityButtonTargetsLocked(userState);
- updateAccessibilityQsTargetsLocked(userState);
+ updateAccessibilityShortcutTargetsLocked(userState, HARDWARE);
+ updateAccessibilityShortcutTargetsLocked(userState, SOFTWARE);
+ updateAccessibilityShortcutTargetsLocked(userState, GESTURE);
+ updateAccessibilityShortcutTargetsLocked(userState, QUICK_SETTINGS);
// Update the capabilities before the mode because we will check the current mode is
// invalid or not..
updateMagnificationCapabilitiesSettingsChangeLocked(userState);
@@ -3204,6 +3209,7 @@
somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, HARDWARE);
somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, QUICK_SETTINGS);
somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, SOFTWARE);
+ somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, GESTURE);
somethingChanged |= readAccessibilityButtonTargetComponentLocked(userState);
somethingChanged |= readUserRecommendedUiTimeoutSettingsLocked(userState);
somethingChanged |= readMagnificationModeForDefaultDisplayLocked(userState);
@@ -3419,27 +3425,6 @@
return false;
}
- /**
- * Check if the target that will be enabled by the accessibility shortcut key is installed.
- * If it isn't, remove it from the list and associated setting so a side loaded service can't
- * spoof the package name of the default service.
- */
- private void updateAccessibilityShortcutKeyTargetsLocked(AccessibilityUserState userState) {
- final Set<String> currentTargets =
- userState.getShortcutTargetsLocked(HARDWARE);
- currentTargets.removeIf(
- name -> !userState.isShortcutTargetInstalledLocked(name));
- if (!userState.updateShortcutTargetsLocked(currentTargets, HARDWARE)) {
- return;
- }
-
- // Update setting key with new value.
- persistColonDelimitedSetToSettingLocked(
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
- userState.mUserId, currentTargets, str -> str);
- scheduleNotifyClientsOfServicesStateChangeLocked(userState);
- }
-
private boolean canRequestAndRequestsTouchExplorationLocked(
AccessibilityServiceConnection service, AccessibilityUserState userState) {
// Service not ready or cannot request the feature - well nothing to do.
@@ -3598,31 +3583,56 @@
}
/**
- * 1) Update accessibility button availability to accessibility services.
- * 2) Check if the target that will be enabled by the accessibility button is installed.
- * If it isn't, remove it from the list and associated setting so a side loaded service can't
- * spoof the package name of the default service.
+ * Adds or removes shortcut targets based on other attributes in the UserState.
+ * <P></P>
+ * Any target is removed if it is no longer installed on device.
+ * For software shortcuts,
+ * the function also updates the availability of the a11y button for services that request it.
+ * For quick settings shortcuts,
+ * targets are added if their service is enabled and has a corresponding QS panel.
*/
- private void updateAccessibilityButtonTargetsLocked(AccessibilityUserState userState) {
- // Update accessibility button availability.
- for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
- final AccessibilityServiceConnection service = userState.mBoundServices.get(i);
- if (service.mRequestAccessibilityButton) {
- service.notifyAccessibilityButtonAvailabilityChangedLocked(
- service.isAccessibilityButtonAvailableLocked(userState));
+ private void updateAccessibilityShortcutTargetsLocked(
+ AccessibilityUserState userState, @UserShortcutType int shortcutType) {
+ if (shortcutType == QUICK_SETTINGS && !android.view.accessibility.Flags.a11yQsShortcut()) {
+ return;
+ }
+ if (shortcutType == SOFTWARE) {
+ // Update accessibility button availability.
+ for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
+ final AccessibilityServiceConnection service = userState.mBoundServices.get(i);
+ if (service.mRequestAccessibilityButton) {
+ service.notifyAccessibilityButtonAvailabilityChangedLocked(
+ service.isAccessibilityButtonAvailableLocked(userState));
+ }
}
}
+ // Remove targets that are no longer installed on device.
final Set<String> currentTargets =
- userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE);
+ userState.getShortcutTargetsLocked(shortcutType);
currentTargets.removeIf(
name -> !userState.isShortcutTargetInstalledLocked(name));
- if (!userState.updateShortcutTargetsLocked(currentTargets, SOFTWARE)) {
+
+ if (shortcutType == QUICK_SETTINGS) {
+ // Add the target if the a11y service is enabled and the tile exist in QS panel
+ Set<ComponentName> enabledServices = userState.getEnabledServicesLocked();
+ Map<ComponentName, ComponentName> a11yFeatureToTileService =
+ userState.getA11yFeatureToTileService();
+ Set<ComponentName> currentA11yTilesInQsPanel = userState.getA11yQsTilesInQsPanel();
+ for (ComponentName enabledService : enabledServices) {
+ ComponentName tileService =
+ a11yFeatureToTileService.getOrDefault(enabledService, null);
+ if (tileService != null && currentA11yTilesInQsPanel.contains(tileService)) {
+ currentTargets.add(enabledService.flattenToString());
+ }
+ }
+ }
+ // Update targets in userState
+ if (!userState.updateShortcutTargetsLocked(currentTargets, shortcutType)) {
return;
}
-
- // Update setting key with new value.
- persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+ // If there was a change to the targets in userState, save the new targets to Settings.
+ persistColonDelimitedSetToSettingLocked(ShortcutUtils.convertToKey(shortcutType),
userState.mUserId, currentTargets, str -> str);
scheduleNotifyClientsOfServicesStateChangeLocked(userState);
}
@@ -3729,49 +3739,6 @@
}
/**
- * Update the Settings.Secure.ACCESSIBILITY_QS_TARGETS so that it only contains valid content,
- * and a side loaded service can't spoof the package name of the default service.
- * <p>
- * 1. Remove the target if the target is no longer installed on the device <br/>
- * 2. Add the target if the target is enabled and the target's tile is in the QS Panel <br/>
- * </p>
- */
- private void updateAccessibilityQsTargetsLocked(AccessibilityUserState userState) {
- if (!android.view.accessibility.Flags.a11yQsShortcut()) {
- return;
- }
-
- final Set<String> targets =
- userState.getShortcutTargetsLocked(QUICK_SETTINGS);
-
- // Removes the targets that are no longer installed on the device.
- targets.removeIf(
- name -> !userState.isShortcutTargetInstalledLocked(name));
- // Add the target if the a11y service is enabled and the tile exist in QS panel
- Set<ComponentName> enabledServices = userState.getEnabledServicesLocked();
- Map<ComponentName, ComponentName> a11yFeatureToTileService =
- userState.getA11yFeatureToTileService();
- Set<ComponentName> currentA11yTilesInQsPanel = userState.getA11yQsTilesInQsPanel();
- for (ComponentName enabledService : enabledServices) {
- ComponentName tileService =
- a11yFeatureToTileService.getOrDefault(enabledService, null);
- if (tileService != null && currentA11yTilesInQsPanel.contains(tileService)) {
- targets.add(enabledService.flattenToString());
- }
- }
-
- if (!userState.updateShortcutTargetsLocked(targets, QUICK_SETTINGS)) {
- return;
- }
-
- // Update setting key with new value.
- persistColonDelimitedSetToSettingLocked(
- Settings.Secure.ACCESSIBILITY_QS_TARGETS,
- userState.mUserId, targets, str -> str);
- scheduleNotifyClientsOfServicesStateChangeLocked(userState);
- }
-
- /**
* Remove the shortcut target for the unbound service which is requesting accessibility button
* and targeting sdk > Q from the accessibility button and shortcut.
*
@@ -3786,23 +3753,19 @@
return;
}
- final List<Pair<Integer, String>> shortcutTypeAndShortcutSetting = new ArrayList<>(3);
- shortcutTypeAndShortcutSetting.add(
- new Pair<>(HARDWARE,
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
- shortcutTypeAndShortcutSetting.add(
- new Pair<>(UserShortcutType.SOFTWARE,
- Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
+ final List<Integer> shortcutTypes = new ArrayList<>(4);
+ shortcutTypes.add(HARDWARE);
+ shortcutTypes.add(SOFTWARE);
if (android.view.accessibility.Flags.a11yQsShortcut()) {
- shortcutTypeAndShortcutSetting.add(
- new Pair<>(QUICK_SETTINGS,
- Settings.Secure.ACCESSIBILITY_QS_TARGETS));
+ shortcutTypes.add(QUICK_SETTINGS);
+ }
+ if (android.provider.Flags.a11yStandaloneGestureEnabled()) {
+ shortcutTypes.add(GESTURE);
}
final ComponentName serviceName = service.getComponentName();
- for (Pair<Integer, String> shortcutTypePair : shortcutTypeAndShortcutSetting) {
- int shortcutType = shortcutTypePair.first;
- String shortcutSettingName = shortcutTypePair.second;
+ for (Integer shortcutType: shortcutTypes) {
+ String shortcutSettingName = ShortcutUtils.convertToKey(shortcutType);
if (userState.removeShortcutTargetLocked(shortcutType, serviceName)) {
final Set<String> currentTargets = userState.getShortcutTargetsLocked(shortcutType);
persistColonDelimitedSetToSettingLocked(
@@ -3934,7 +3897,7 @@
.isActivated(displayId);
logAccessibilityShortcutActivated(mContext, MAGNIFICATION_COMPONENT_NAME, shortcutType,
enabled);
- sendAccessibilityButtonToInputFilter(displayId);
+ notifyMagnificationShortcutTriggered(displayId);
return;
}
final ComponentName targetComponentName = ComponentName.unflattenFromString(targetName);
@@ -4104,6 +4067,11 @@
boolean enable, @UserShortcutType int shortcutTypes,
@NonNull List<String> shortcutTargets, @UserIdInt int userId) {
enableShortcutsForTargets_enforcePermission();
+ if ((shortcutTypes & GESTURE) == GESTURE
+ && !android.provider.Flags.a11yStandaloneGestureEnabled()) {
+ throw new IllegalArgumentException(
+ "GESTURE type shortcuts are disabled by feature flag");
+ }
for (int shortcutType : USER_SHORTCUT_TYPES) {
if ((shortcutTypes & shortcutType) == shortcutType) {
enableShortcutForTargets(enable, shortcutType, shortcutTargets, userId);
@@ -4202,7 +4170,7 @@
AccessibilityShortcutController.DialogStatus.SHOWN
);
}
- } else if (shortcutType == UserShortcutType.SOFTWARE) {
+ } else if (shortcutType == SOFTWARE) {
// Update the A11y FAB size to large when the Magnification shortcut is
// enabled and the user hasn't changed the floating button size
if (shortcutTargets.contains(MAGNIFICATION_CONTROLLER_NAME)
@@ -4372,7 +4340,7 @@
final AccessibilityUserState userState = getCurrentUserStateLocked();
final ArrayList<String> shortcutTargets = new ArrayList<>(
userState.getShortcutTargetsLocked(shortcutType));
- if (shortcutType != UserShortcutType.SOFTWARE) {
+ if (shortcutType != SOFTWARE) {
return shortcutTargets;
}
// Adds legacy a11y services requesting a11y button into the list.
@@ -5487,6 +5455,9 @@
private final Uri mAccessibilityButtonTargetsUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+ private final Uri mAccessibilityGestureTargetsUri = Settings.Secure.getUriFor(
+ Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS);
+
private final Uri mUserNonInteractiveUiTimeoutUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS);
@@ -5540,6 +5511,8 @@
contentResolver.registerContentObserver(
mAccessibilityButtonTargetsUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
+ mAccessibilityGestureTargetsUri, false, this, UserHandle.USER_ALL);
+ contentResolver.registerContentObserver(
mUserNonInteractiveUiTimeoutUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
mUserInteractiveUiTimeoutUri, false, this, UserHandle.USER_ALL);
@@ -5611,6 +5584,10 @@
if (readAccessibilityShortcutTargetsLocked(userState, SOFTWARE)) {
onUserStateChangedLocked(userState);
}
+ } else if (mAccessibilityGestureTargetsUri.equals(uri)) {
+ if (readAccessibilityShortcutTargetsLocked(userState, GESTURE)) {
+ onUserStateChangedLocked(userState);
+ }
} else if (mUserNonInteractiveUiTimeoutUri.equals(uri)
|| mUserInteractiveUiTimeoutUri.equals(uri)) {
readUserRecommendedUiTimeoutSettingsLocked(userState);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index de1c86a..7bcbc27 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -27,6 +27,12 @@
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TRIPLETAP;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TWOFINGER_DOUBLETAP;
import android.accessibilityservice.AccessibilityService.SoftKeyboardShowMode;
import android.accessibilityservice.AccessibilityServiceInfo;
@@ -98,9 +104,10 @@
final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<>();
- final ArraySet<String> mAccessibilityShortcutKeyTargets = new ArraySet<>();
+ private final ArraySet<String> mAccessibilityShortcutKeyTargets = new ArraySet<>();
- final ArraySet<String> mAccessibilityButtonTargets = new ArraySet<>();
+ private final ArraySet<String> mAccessibilityButtonTargets = new ArraySet<>();
+ private final ArraySet<String> mAccessibilityGestureTargets = new ArraySet<>();
private final ArraySet<String> mAccessibilityQsTargets = new ArraySet<>();
/**
@@ -224,6 +231,7 @@
mTouchExplorationGrantedServices.clear();
mAccessibilityShortcutKeyTargets.clear();
mAccessibilityButtonTargets.clear();
+ mAccessibilityGestureTargets.clear();
mTargetAssignedToAccessibilityButton = null;
mIsTouchExplorationEnabled = false;
mServiceHandlesDoubleTap = false;
@@ -524,6 +532,20 @@
}
}
+ private void dumpShortcutTargets(
+ PrintWriter pw, @UserShortcutType int shortcutType, String name) {
+ pw.append(" ").append(name).append(":{");
+ ArraySet<String> targets = getShortcutTargetsInternalLocked(shortcutType);
+ int size = targets.size();
+ for (int i = 0; i < size; i++) {
+ if (i > 0) {
+ pw.append(", ");
+ }
+ pw.append(targets.valueAt(i));
+ }
+ pw.println("}");
+ }
+
void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.append("User state[");
pw.println();
@@ -553,30 +575,12 @@
.append(String.valueOf(mAlwaysOnMagnificationEnabled));
pw.append("}");
pw.println();
- pw.append(" shortcut key:{");
- int size = mAccessibilityShortcutKeyTargets.size();
- for (int i = 0; i < size; i++) {
- final String componentId = mAccessibilityShortcutKeyTargets.valueAt(i);
- pw.append(componentId);
- if (i + 1 < size) {
- pw.append(", ");
- }
- }
- pw.println("}");
- pw.append(" button:{");
- size = mAccessibilityButtonTargets.size();
- for (int i = 0; i < size; i++) {
- final String componentId = mAccessibilityButtonTargets.valueAt(i);
- pw.append(componentId);
- if (i + 1 < size) {
- pw.append(", ");
- }
- }
- pw.println("}");
+ dumpShortcutTargets(pw, HARDWARE, "shortcut key");
+ dumpShortcutTargets(pw, SOFTWARE, "button");
pw.append(" button target:{").append(mTargetAssignedToAccessibilityButton);
pw.println("}");
- pw.append(" qs shortcut targets:").append(mAccessibilityQsTargets.toString());
- pw.println();
+ dumpShortcutTargets(pw, GESTURE, "gesture");
+ dumpShortcutTargets(pw, QUICK_SETTINGS, "qs shortcut targets");
pw.append(" a11y tiles in QS panel:").append(mA11yTilesInQsPanel.toString());
pw.println();
pw.append(" Bound services:{");
@@ -771,7 +775,8 @@
/**
* Returns a set which contains the flattened component names and the system class names
- * assigned to the given shortcut.
+ * assigned to the given shortcut. The set is a defensive copy. To apply any changes to the set,
+ * use {@link #updateShortcutTargetsLocked(Set, int)}
*
* @param shortcutType The shortcut type.
* @return The array set of the strings
@@ -779,16 +784,19 @@
public ArraySet<String> getShortcutTargetsLocked(@UserShortcutType int shortcutType) {
return new ArraySet<>(getShortcutTargetsInternalLocked(shortcutType));
}
+
private ArraySet<String> getShortcutTargetsInternalLocked(@UserShortcutType int shortcutType) {
- if (shortcutType == UserShortcutType.HARDWARE) {
+ if (shortcutType == HARDWARE) {
return mAccessibilityShortcutKeyTargets;
- } else if (shortcutType == UserShortcutType.SOFTWARE) {
+ } else if (shortcutType == SOFTWARE) {
return mAccessibilityButtonTargets;
- } else if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
+ } else if (shortcutType == GESTURE) {
+ return mAccessibilityGestureTargets;
+ } else if (shortcutType == QUICK_SETTINGS) {
return mAccessibilityQsTargets;
- } else if ((shortcutType == UserShortcutType.TRIPLETAP
+ } else if ((shortcutType == TRIPLETAP
&& isMagnificationSingleFingerTripleTapEnabledLocked()) || (
- shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP
+ shortcutType == TWOFINGER_DOUBLETAP
&& isMagnificationTwoFingerTripleTapEnabledLocked())) {
ArraySet<String> targets = new ArraySet<>();
targets.add(MAGNIFICATION_CONTROLLER_NAME);
@@ -809,7 +817,7 @@
*/
boolean updateShortcutTargetsLocked(
Set<String> newTargets, @UserShortcutType int shortcutType) {
- final int mask = UserShortcutType.TRIPLETAP | UserShortcutType.TWOFINGER_DOUBLETAP;
+ final int mask = TRIPLETAP | TWOFINGER_DOUBLETAP;
if ((shortcutType & mask) != 0) {
throw new IllegalArgumentException("Tap shortcuts cannot be updated with target sets.");
}
@@ -857,7 +865,7 @@
}
/**
- * Removes given shortcut target in the list.
+ * Removes given shortcut target in the set.
*
* @param shortcutType The shortcut type.
* @param target The component name of the shortcut target.
@@ -865,8 +873,8 @@
*/
public boolean removeShortcutTargetLocked(
@UserShortcutType int shortcutType, ComponentName target) {
- if (shortcutType == UserShortcutType.TRIPLETAP
- || shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {
+ if (shortcutType == TRIPLETAP
+ || shortcutType == TWOFINGER_DOUBLETAP) {
throw new UnsupportedOperationException(
"removeShortcutTargetLocked only support shortcut type: "
+ "software and hardware and quick settings for now"
diff --git a/services/autofill/java/com/android/server/autofill/RequestId.java b/services/autofill/java/com/android/server/autofill/RequestId.java
index 29ad786..d8069a8 100644
--- a/services/autofill/java/com/android/server/autofill/RequestId.java
+++ b/services/autofill/java/com/android/server/autofill/RequestId.java
@@ -16,8 +16,14 @@
package com.android.server.autofill;
-import java.util.List;
+import static com.android.server.autofill.Helper.sDebug;
+
+import android.util.Slog;
+import android.util.SparseArray;
+
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.List;
+import java.util.Random;
// Helper class containing various methods to deal with FillRequest Ids.
// For authentication flows, there needs to be a way to know whether to retrieve the Fill
@@ -25,56 +31,97 @@
// way to achieve this is by assigning odd number request ids to secondary provider and
// even numbers to primary provider.
public class RequestId {
+ private AtomicInteger sIdCounter;
- private AtomicInteger sIdCounter;
+ // The minimum request id is 2 to avoid possible authentication issues.
+ static final int MIN_REQUEST_ID = 2;
+ // The maximum request id is 0x7FFF to make sure the 16th bit is 0.
+ // This is to make sure the authentication id is always positive.
+ static final int MAX_REQUEST_ID = 0x7FFF; // 32767
- // Mainly used for tests
- RequestId(int start) {
- sIdCounter = new AtomicInteger(start);
- }
+ // The maximum start id is made small to best avoid wrapping around.
+ static final int MAX_START_ID = 1000;
+ // The magic number is used to determine if a wrap has happened.
+ // The underlying assumption of MAGIC_NUMBER is that there can't be as many as MAGIC_NUMBER
+ // of fill requests in one session. so there can't be as many as MAGIC_NUMBER of fill requests
+ // getting dropped.
+ static final int MAGIC_NUMBER = 5000;
- public RequestId() {
- this((int) (Math.floor(Math.random() * 0xFFFF)));
- }
+ static final int MIN_PRIMARY_REQUEST_ID = 2;
+ static final int MAX_PRIMARY_REQUEST_ID = 0x7FFE; // 32766
- public static int getLastRequestIdIndex(List<Integer> requestIds) {
- int lastId = -1;
- int indexOfBiggest = -1;
- // Biggest number is usually the latest request, since IDs only increase
- // The only exception is when the request ID wraps around back to 0
- for (int i = requestIds.size() - 1; i >= 0; i--) {
- if (requestIds.get(i) > lastId) {
- lastId = requestIds.get(i);
- indexOfBiggest = i;
- }
- }
+ static final int MIN_SECONDARY_REQUEST_ID = 3;
+ static final int MAX_SECONDARY_REQUEST_ID = 0x7FFF; // 32767
- // 0xFFFE + 2 == 0x1 (for secondary)
- // 0xFFFD + 2 == 0x0 (for primary)
- // Wrap has occurred
- if (lastId >= 0xFFFD) {
- // Calculate the biggest size possible
- // If list only has one kind of request ids - we need to multiple by 2
- // (since they skip odd ints)
- // Also subtract one from size because at least one integer exists pre-wrap
- int calcSize = (requestIds.size()) * 2;
- //Biggest possible id after wrapping
- int biggestPossible = (lastId + calcSize) % 0xFFFF;
- lastId = -1;
- indexOfBiggest = -1;
- for (int i = 0; i < requestIds.size(); i++) {
- int currentId = requestIds.get(i);
- if (currentId <= biggestPossible && currentId > lastId) {
- lastId = currentId;
- indexOfBiggest = i;
+ private static final String TAG = "RequestId";
+
+ // WARNING: This constructor should only be used for testing
+ RequestId(int startId) {
+ if (startId < MIN_REQUEST_ID || startId > MAX_REQUEST_ID) {
+ throw new IllegalArgumentException("startId must be between " + MIN_REQUEST_ID +
+ " and " + MAX_REQUEST_ID);
}
- }
+ if (sDebug) {
+ Slog.d(TAG, "RequestId(int): startId= " + startId);
+ }
+ sIdCounter = new AtomicInteger(startId);
}
- return indexOfBiggest;
- }
+ // WARNING: This get method should only be used for testing
+ int getRequestId() {
+ return sIdCounter.get();
+ }
- public int nextId(boolean isSecondary) {
+ public RequestId() {
+ Random random = new Random();
+ int low = MIN_REQUEST_ID;
+ int high = MAX_START_ID + 1; // nextInt is exclusive on upper limit
+
+ // Generate a random start request id that >= MIN_REQUEST_ID and <= MAX_START_ID
+ int startId = random.nextInt(high - low) + low;
+ if (sDebug) {
+ Slog.d(TAG, "RequestId(): startId= " + startId);
+ }
+ sIdCounter = new AtomicInteger(startId);
+ }
+
+ // Given a list of request ids, find the index of the last request id.
+ // Note: Since the request id wraps around, the largest request id may not be
+ // the latest request id.
+ //
+ // @param requestIds List of request ids in ascending order with at least one element.
+ // @return Index of the last request id.
+ public static int getLastRequestIdIndex(List<Integer> requestIds) {
+ // If there is only one request id, return index as 0.
+ if (requestIds.size() == 1) {
+ return 0;
+ }
+
+ // We have to use a magical number to determine if a wrap has happened because
+ // the request id could be lost. The underlying assumption of MAGIC_NUMBER is that
+ // there can't be as many as MAGIC_NUMBER of fill requests in one session.
+ boolean wrapHasHappened = false;
+ int latestRequestIdIndex = -1;
+
+ for (int i = 0; i < requestIds.size() - 1; i++) {
+ if (requestIds.get(i+1) - requestIds.get(i) > MAGIC_NUMBER) {
+ wrapHasHappened = true;
+ latestRequestIdIndex = i;
+ break;
+ }
+ }
+
+ // If there was no wrap, the last request index is the last index.
+ if (!wrapHasHappened) {
+ latestRequestIdIndex = requestIds.size() - 1;
+ }
+ if (sDebug) {
+ Slog.d(TAG, "getLastRequestIdIndex(): latestRequestIdIndex = " + latestRequestIdIndex);
+ }
+ return latestRequestIdIndex;
+ }
+
+ public int nextId(boolean isSecondary) {
// For authentication flows, there needs to be a way to know whether to retrieve the Fill
// Response from the primary provider or the secondary provider from the requestId. A simple
// way to achieve this is by assigning odd number request ids to secondary provider and
@@ -82,13 +129,20 @@
int requestId;
do {
- requestId = sIdCounter.incrementAndGet() % 0xFFFF;
+ requestId = sIdCounter.incrementAndGet() % (MAX_REQUEST_ID + 1);
+ // Skip numbers smaller than MIN_REQUEST_ID to avoid possible authentication issue
+ if (requestId < MIN_REQUEST_ID) {
+ requestId = MIN_REQUEST_ID;
+ }
sIdCounter.set(requestId);
} while (isSecondaryProvider(requestId) != isSecondary);
+ if (sDebug) {
+ Slog.d(TAG, "nextId(): requestId = " + requestId);
+ }
return requestId;
- }
+ }
- public static boolean isSecondaryProvider(int requestId) {
- return requestId % 2 == 1;
- }
+ public static boolean isSecondaryProvider(int requestId) {
+ return requestId % 2 == 1;
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 494e956..c6ddc16 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -6902,17 +6902,18 @@
return mPendingSaveUi != null && mPendingSaveUi.getState() == PendingUi.STATE_PENDING;
}
+ // Return latest response index in mResponses SparseArray.
@GuardedBy("mLock")
private int getLastResponseIndexLocked() {
- if (mResponses != null) {
- List<Integer> requestIdList = new ArrayList<>();
- final int responseCount = mResponses.size();
- for (int i = 0; i < responseCount; i++) {
- requestIdList.add(mResponses.keyAt(i));
- }
- return mRequestId.getLastRequestIdIndex(requestIdList);
+ if (mResponses == null || mResponses.size() == 0) {
+ return -1;
}
- return -1;
+ List<Integer> requestIdList = new ArrayList<>();
+ final int responseCount = mResponses.size();
+ for (int i = 0; i < responseCount; i++) {
+ requestIdList.add(mResponses.keyAt(i));
+ }
+ return mRequestId.getLastRequestIdIndex(requestIdList);
}
private LogMaker newLogMaker(int category) {
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index afeafa4..988a213 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -87,15 +87,6 @@
void onSecureWindowShown(int displayId, int uid);
}
- /**
- * For communicating when activities are blocked from entering PIP on the display by this
- * policy controller.
- */
- public interface PipBlockedCallback {
- /** Called when an activity is blocked from entering PIP. */
- void onEnteringPipBlocked(int uid);
- }
-
/** Interface to listen for interception of intents. */
public interface IntentListenerCallback {
/** Returns true when an intent should be intercepted */
@@ -136,7 +127,6 @@
@GuardedBy("mGenericWindowPolicyControllerLock")
private final ArraySet<Integer> mRunningUids = new ArraySet<>();
@Nullable private final ActivityListener mActivityListener;
- @Nullable private final PipBlockedCallback mPipBlockedCallback;
@Nullable private final IntentListenerCallback mIntentListenerCallback;
private final Handler mHandler = new Handler(Looper.getMainLooper());
@NonNull
@@ -190,7 +180,6 @@
@NonNull Set<ComponentName> crossTaskNavigationExemptions,
@Nullable ComponentName permissionDialogComponent,
@Nullable ActivityListener activityListener,
- @Nullable PipBlockedCallback pipBlockedCallback,
@Nullable ActivityBlockedCallback activityBlockedCallback,
@Nullable SecureWindowCallback secureWindowCallback,
@Nullable IntentListenerCallback intentListenerCallback,
@@ -208,7 +197,6 @@
mActivityBlockedCallback = activityBlockedCallback;
setInterestedWindowFlags(windowFlags, systemWindowFlags);
mActivityListener = activityListener;
- mPipBlockedCallback = pipBlockedCallback;
mSecureWindowCallback = secureWindowCallback;
mIntentListenerCallback = intentListenerCallback;
mDisplayCategories = displayCategories;
@@ -346,6 +334,10 @@
}
final UserHandle activityUser =
UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid);
+ if (!activityUser.isSystem() && !mAllowedUsers.contains(activityUser)) {
+ logActivityLaunchBlocked("Activity launch disallowed from user " + activityUser);
+ return false;
+ }
final ComponentName activityComponent = activityInfo.getComponentName();
if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent) && activityUser.isSystem()) {
// The error dialog alerting users that streaming is blocked is always allowed.
@@ -464,18 +456,6 @@
return mShowTasksInHostDeviceRecents;
}
}
-
- @Override
- public boolean isEnteringPipAllowed(int uid) {
- if (super.isEnteringPipAllowed(uid)) {
- return true;
- }
- if (mPipBlockedCallback != null) {
- mHandler.post(() -> mPipBlockedCallback.onEnteringPipBlocked(uid));
- }
- return false;
- }
-
@Override
public @Nullable ComponentName getCustomHomeComponent() {
return mCustomHomeComponent;
@@ -512,7 +492,6 @@
"virtual_devices.value_activity_blocked_count",
mAttributionSource.getUid());
}
-
}
private static boolean isAllowedByPolicy(boolean allowedByDefault,
diff --git a/services/companion/java/com/android/server/companion/virtual/InputController.java b/services/companion/java/com/android/server/companion/virtual/InputController.java
index 70af49c..d091ce8 100644
--- a/services/companion/java/com/android/server/companion/virtual/InputController.java
+++ b/services/companion/java/com/android/server/companion/virtual/InputController.java
@@ -31,6 +31,7 @@
import android.hardware.input.VirtualMouseButtonEvent;
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
+import android.hardware.input.VirtualRotaryEncoderScrollEvent;
import android.hardware.input.VirtualStylusButtonEvent;
import android.hardware.input.VirtualStylusMotionEvent;
import android.hardware.input.VirtualTouchEvent;
@@ -76,6 +77,7 @@
static final String PHYS_TYPE_TOUCHSCREEN = "Touchscreen";
static final String PHYS_TYPE_NAVIGATION_TOUCHPAD = "NavigationTouchpad";
static final String PHYS_TYPE_STYLUS = "Stylus";
+ static final String PHYS_TYPE_ROTARY_ENCODER = "RotaryEncoder";
@StringDef(prefix = { "PHYS_TYPE_" }, value = {
PHYS_TYPE_DPAD,
PHYS_TYPE_KEYBOARD,
@@ -83,6 +85,7 @@
PHYS_TYPE_TOUCHSCREEN,
PHYS_TYPE_NAVIGATION_TOUCHPAD,
PHYS_TYPE_STYLUS,
+ PHYS_TYPE_ROTARY_ENCODER,
})
@Retention(RetentionPolicy.SOURCE)
@interface PhysType {
@@ -206,6 +209,15 @@
height, width));
}
+ void createRotaryEncoder(@NonNull String deviceName, int vendorId, int productId,
+ @NonNull IBinder deviceToken, int displayId) throws DeviceCreationException {
+ final String phys = createPhys(PHYS_TYPE_ROTARY_ENCODER);
+ createDeviceInternal(InputDeviceDescriptor.TYPE_ROTARY_ENCODER, deviceName, vendorId,
+ productId, deviceToken, displayId, phys,
+ () -> mNativeWrapper.openUinputRotaryEncoder(deviceName, vendorId, productId,
+ phys));
+ }
+
void unregisterInputDevice(@NonNull IBinder token) {
synchronized (mLock) {
final InputDeviceDescriptor inputDeviceDescriptor = mInputDeviceDescriptors.remove(
@@ -403,6 +415,20 @@
}
}
+ boolean sendRotaryEncoderScrollEvent(@NonNull IBinder token,
+ @NonNull VirtualRotaryEncoderScrollEvent event) {
+ synchronized (mLock) {
+ final InputDeviceDescriptor inputDeviceDescriptor = mInputDeviceDescriptors.get(
+ token);
+ if (inputDeviceDescriptor == null) {
+ return false;
+ }
+ return mNativeWrapper.writeRotaryEncoderScrollEvent(
+ inputDeviceDescriptor.getNativePointer(), event.getScrollAmount(),
+ event.getEventTimeNanos());
+ }
+ }
+
public void dump(@NonNull PrintWriter fout) {
fout.println(" InputController: ");
synchronized (mLock) {
@@ -449,6 +475,9 @@
int productId, String phys, int height, int width);
private static native long nativeOpenUinputStylus(String deviceName, int vendorId,
int productId, String phys, int height, int width);
+ private static native long nativeOpenUinputRotaryEncoder(String deviceName, int vendorId,
+ int productId, String phys);
+
private static native void nativeCloseUinput(long ptr);
private static native boolean nativeWriteDpadKeyEvent(long ptr, int androidKeyCode, int action,
long eventTimeNanos);
@@ -467,6 +496,8 @@
int locationX, int locationY, int pressure, int tiltX, int tiltY, long eventTimeNanos);
private static native boolean nativeWriteStylusButtonEvent(long ptr, int buttonCode, int action,
long eventTimeNanos);
+ private static native boolean nativeWriteRotaryEncoderScrollEvent(long ptr, float scrollAmount,
+ long eventTimeNanos);
/** Wrapper around the static native methods for tests. */
@VisibleForTesting
@@ -495,6 +526,11 @@
return nativeOpenUinputStylus(deviceName, vendorId, productId, phys, height, width);
}
+ public long openUinputRotaryEncoder(String deviceName, int vendorId, int productId,
+ String phys) {
+ return nativeOpenUinputRotaryEncoder(deviceName, vendorId, productId, phys);
+ }
+
public void closeUinput(long ptr) {
nativeCloseUinput(ptr);
}
@@ -542,6 +578,11 @@
long eventTimeNanos) {
return nativeWriteStylusButtonEvent(ptr, buttonCode, action, eventTimeNanos);
}
+
+ public boolean writeRotaryEncoderScrollEvent(long ptr, float scrollAmount,
+ long eventTimeNanos) {
+ return nativeWriteRotaryEncoderScrollEvent(ptr, scrollAmount, eventTimeNanos);
+ }
}
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -553,6 +594,7 @@
static final int TYPE_DPAD = 4;
static final int TYPE_NAVIGATION_TOUCHPAD = 5;
static final int TYPE_STYLUS = 6;
+ static final int TYPE_ROTARY_ENCODER = 7;
@IntDef(prefix = { "TYPE_" }, value = {
TYPE_KEYBOARD,
TYPE_MOUSE,
@@ -560,6 +602,7 @@
TYPE_DPAD,
TYPE_NAVIGATION_TOUCHPAD,
TYPE_STYLUS,
+ TYPE_ROTARY_ENCODER,
})
@Retention(RetentionPolicy.SOURCE)
@interface Type {
@@ -821,6 +864,8 @@
return "virtual_devices.value_virtual_navigationtouchpad_created_count";
case InputDeviceDescriptor.TYPE_STYLUS:
return "virtual_devices.value_virtual_stylus_created_count";
+ case InputDeviceDescriptor.TYPE_ROTARY_ENCODER:
+ return "virtual_devices.value_virtual_rotary_created_count";
default:
Log.e(TAG, "No metric known for input type: " + type);
return null;
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 6704049..7d9d660 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -24,6 +24,7 @@
import static android.companion.virtual.VirtualDeviceParams.NAVIGATION_POLICY_DEFAULT_ALLOWED;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_ACTIVITY;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO;
+import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS;
@@ -77,6 +78,8 @@
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualNavigationTouchpadConfig;
+import android.hardware.input.VirtualRotaryEncoderConfig;
+import android.hardware.input.VirtualRotaryEncoderScrollEvent;
import android.hardware.input.VirtualStylusButtonEvent;
import android.hardware.input.VirtualStylusConfig;
import android.hardware.input.VirtualStylusMotionEvent;
@@ -183,8 +186,9 @@
private final SparseIntArray mDevicePolicies;
@GuardedBy("mVirtualDeviceLock")
private final SparseArray<VirtualDisplayWrapper> mVirtualDisplays = new SparseArray<>();
- private final IVirtualDeviceActivityListener mActivityListener;
- private final IVirtualDeviceSoundEffectListener mSoundEffectListener;
+ private IVirtualDeviceActivityListener mActivityListener;
+ private ActivityListener mActivityListenerAdapter = null;
+ private IVirtualDeviceSoundEffectListener mSoundEffectListener;
private final DisplayManagerGlobal mDisplayManager;
private final DisplayManagerInternal mDisplayManagerInternal;
@GuardedBy("mVirtualDeviceLock")
@@ -237,6 +241,16 @@
Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e);
}
}
+
+ @Override
+ public void onActivityLaunchBlocked(int displayId,
+ @NonNull ComponentName componentName, @UserIdInt int userId) {
+ try {
+ mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e);
+ }
+ }
};
}
@@ -301,7 +315,9 @@
UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(attributionSource.getUid());
mContext = context.createContextAsUser(ownerUserHandle, 0);
mAssociationInfo = associationInfo;
- mPersistentDeviceId = createPersistentDeviceId(associationInfo.getId());
+ mPersistentDeviceId = associationInfo == null
+ ? null
+ : createPersistentDeviceId(associationInfo.getId());
mService = service;
mPendingTrampolineCallback = pendingTrampolineCallback;
mActivityListener = activityListener;
@@ -403,7 +419,7 @@
/** Returns the device display name. */
CharSequence getDisplayName() {
- return mAssociationInfo.getDisplayName();
+ return mAssociationInfo == null ? mParams.getName() : mAssociationInfo.getDisplayName();
}
/** Returns the public representation of the device. */
@@ -418,6 +434,22 @@
}
}
+ /**
+ * Setter for listeners that live in the client process, namely in
+ * {@link android.companion.virtual.VirtualDeviceInternal}.
+ *
+ * This is needed for virtual devices that are created by the system, as the VirtualDeviceImpl
+ * object is created before the returned VirtualDeviceInternal one.
+ */
+ @Override // Binder call
+ @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ public void setListeners(@NonNull IVirtualDeviceActivityListener activityListener,
+ @NonNull IVirtualDeviceSoundEffectListener soundEffectListener) {
+ super.setListeners_enforcePermission();
+ mActivityListener = Objects.requireNonNull(activityListener);
+ mSoundEffectListener = Objects.requireNonNull(soundEffectListener);
+ }
+
@Override // Binder call
public @VirtualDeviceParams.DevicePolicy int getDevicePolicy(
@VirtualDeviceParams.PolicyType int policyType) {
@@ -454,7 +486,9 @@
@Override // Binder call
public int getAssociationId() {
- return mAssociationInfo.getId();
+ return mAssociationInfo == null
+ ? VirtualDeviceManagerService.CDM_ASSOCIATION_ID_NONE
+ : mAssociationInfo.getId();
}
@Override // Binder call
@@ -687,6 +721,13 @@
}
}
break;
+ case POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR:
+ if (android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ synchronized (mVirtualDeviceLock) {
+ mDevicePolicies.put(policyType, devicePolicy);
+ }
+ }
+ break;
default:
throw new IllegalArgumentException("Device policy " + policyType
+ " cannot be changed at runtime. ");
@@ -812,6 +853,26 @@
@Override // Binder call
@EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ public void createVirtualRotaryEncoder(@NonNull VirtualRotaryEncoderConfig config,
+ @NonNull IBinder deviceToken) {
+ super.createVirtualRotaryEncoder_enforcePermission();
+ Objects.requireNonNull(config);
+ Objects.requireNonNull(deviceToken);
+ checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId());
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mInputController.createRotaryEncoder(config.getInputDeviceName(), config.getVendorId(),
+ config.getProductId(), deviceToken,
+ getTargetDisplayIdForInput(config.getAssociatedDisplayId()));
+ } catch (InputController.DeviceCreationException e) {
+ throw new IllegalArgumentException(e);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
public void unregisterInputDevice(IBinder token) {
super.unregisterInputDevice_enforcePermission();
final long ident = Binder.clearCallingIdentity();
@@ -947,6 +1008,19 @@
@Override // Binder call
@EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+ public boolean sendRotaryEncoderScrollEvent(@NonNull IBinder token,
+ @NonNull VirtualRotaryEncoderScrollEvent event) {
+ super.sendRotaryEncoderScrollEvent_enforcePermission();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ return mInputController.sendRotaryEncoderScrollEvent(token, event);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
public void setShowPointerIcon(boolean showPointerIcon) {
super.setShowPointerIcon_enforcePermission();
final long ident = Binder.clearCallingIdentity();
@@ -1105,7 +1179,7 @@
String indent = " ";
fout.println(" VirtualDevice: ");
fout.println(indent + "mDeviceId: " + mDeviceId);
- fout.println(indent + "mAssociationId: " + mAssociationInfo.getId());
+ fout.println(indent + "mAssociationId: " + getAssociationId());
fout.println(indent + "mOwnerPackageName: " + mOwnerPackageName);
fout.println(indent + "mParams: ");
mParams.dump(fout, indent + indent);
@@ -1154,6 +1228,10 @@
final ComponentName homeComponent =
Flags.vdmCustomHome() ? mParams.getHomeComponent() : null;
+ if (mActivityListenerAdapter == null) {
+ mActivityListenerAdapter = createListenerAdapter();
+ }
+
final GenericWindowPolicyController gwpc = new GenericWindowPolicyController(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
@@ -1166,8 +1244,7 @@
? mParams.getBlockedCrossTaskNavigations()
: mParams.getAllowedCrossTaskNavigations(),
mPermissionDialogComponent,
- createListenerAdapter(),
- this::onEnteringPipBlocked,
+ mActivityListenerAdapter,
this::onActivityBlocked,
this::onSecureWindowShown,
this::shouldInterceptIntent,
@@ -1251,12 +1328,37 @@
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
private void onActivityBlocked(int displayId, ActivityInfo activityInfo) {
- Intent intent = BlockedAppStreamingActivity.createIntent(
- activityInfo, mAssociationInfo.getDisplayName());
- mContext.startActivityAsUser(
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK),
- ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle(),
- UserHandle.SYSTEM);
+ Intent intent = BlockedAppStreamingActivity.createIntent(activityInfo, getDisplayName());
+ if (shouldShowBlockedActivityDialog(
+ activityInfo.getComponentName(), intent.getComponent())) {
+ mContext.startActivityAsUser(
+ intent.addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK),
+ ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle(),
+ UserHandle.SYSTEM);
+ }
+
+ if (android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ mActivityListenerAdapter.onActivityLaunchBlocked(
+ displayId,
+ activityInfo.getComponentName(),
+ UserHandle.getUserHandleForUid(
+ activityInfo.applicationInfo.uid).getIdentifier());
+ }
+ }
+
+ private boolean shouldShowBlockedActivityDialog(ComponentName blockedComponent,
+ ComponentName blockedAppStreamingActivityComponent) {
+ if (Objects.equals(blockedComponent, blockedAppStreamingActivityComponent)) {
+ // Do not show the dialog if it was blocked for some reason already to avoid
+ // infinite blocking loop.
+ return false;
+ }
+ if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ return true;
+ }
+ // Do not show the dialog if disabled by policy.
+ return getDevicePolicy(POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR) == DEVICE_POLICY_DEFAULT;
}
private void onSecureWindowShown(int displayId, int uid) {
@@ -1339,7 +1441,7 @@
@SuppressWarnings("AndroidFrameworkRequiresPermission")
private void checkVirtualInputDeviceDisplayIdAssociation(int displayId) {
- if (mContext.checkCallingPermission(android.Manifest.permission.INJECT_EVENTS)
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INJECT_EVENTS)
== PackageManager.PERMISSION_GRANTED) {
// The INJECT_EVENTS permission allows for injecting input to any window / display.
return;
@@ -1456,12 +1558,6 @@
return mInputController.getInputDeviceDescriptors().values().stream().anyMatch(
inputDeviceDescriptor -> inputDeviceDescriptor.getInputDeviceId() == inputDeviceId);
}
-
- void onEnteringPipBlocked(int uid) {
- // Do nothing. ActivityRecord#checkEnterPictureInPictureState logs that the display does not
- // support PiP.
- }
-
void playSoundEffect(int effectType) {
try {
mSoundEffectListener.onPlaySoundEffect(effectType);
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java
index c65aa5b..b0bacfd 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
+import android.os.Process;
import android.util.SparseArray;
import java.io.PrintWriter;
@@ -35,6 +36,8 @@
"MM-dd HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
private static final int MAX_ENTRIES = 16;
+ private static final String VIRTUAL_DEVICE_OWNER_SYSTEM = "system";
+
private final Context mContext;
private final ArrayDeque<LogEntry> mLogEntries = new ArrayDeque<>();
@@ -132,6 +135,8 @@
String[] packages;
if (mUidToPackagesCache.contains(ownerUid)) {
return mUidToPackagesCache.get(ownerUid);
+ } else if (ownerUid == Process.SYSTEM_UID) {
+ return VIRTUAL_DEVICE_OWNER_SYSTEM;
} else {
packages = mPackageManager.getPackagesForUid(ownerUid);
String packageName = "";
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 9ad73ca..1be1d2b 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -101,6 +101,11 @@
AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING);
+ /**
+ * A virtual device association id corresponding to no CDM association.
+ */
+ static final int CDM_ASSOCIATION_ID_NONE = 0;
+
private final Object mVirtualDeviceManagerLock = new Object();
private final VirtualDeviceManagerImpl mImpl;
private final VirtualDeviceManagerNativeImpl mNativeImpl;
@@ -316,7 +321,9 @@
for (int i = 0; i < mVirtualDevices.size(); i++) {
VirtualDeviceImpl virtualDevice = mVirtualDevices.valueAt(i);
- if (!activeAssociationIds.contains(virtualDevice.getAssociationId())) {
+ int deviceAssociationId = virtualDevice.getAssociationId();
+ if (deviceAssociationId != CDM_ASSOCIATION_ID_NONE
+ && !activeAssociationIds.contains(deviceAssociationId)) {
virtualDevicesToRemove.add(virtualDevice);
}
}
@@ -422,28 +429,39 @@
@NonNull IVirtualDeviceActivityListener activityListener,
@NonNull IVirtualDeviceSoundEffectListener soundEffectListener) {
createVirtualDevice_enforcePermission();
- attributionSource.enforceCallingUid();
-
- final int callingUid = getCallingUid();
+ Objects.requireNonNull(activityListener);
+ Objects.requireNonNull(soundEffectListener);
final String packageName = attributionSource.getPackageName();
- if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
- throw new SecurityException(
- "Package name " + packageName + " does not belong to calling uid "
- + callingUid);
- }
AssociationInfo associationInfo = getAssociationInfo(packageName, associationId);
if (associationInfo == null) {
throw new IllegalArgumentException("No association with ID " + associationId);
- }
- if (!VIRTUAL_DEVICE_COMPANION_DEVICE_PROFILES
+ } else if (!VIRTUAL_DEVICE_COMPANION_DEVICE_PROFILES
.contains(associationInfo.getDeviceProfile())
&& Flags.persistentDeviceIdApi()) {
throw new IllegalArgumentException("Unsupported CDM Association device profile "
+ associationInfo.getDeviceProfile() + " for virtual device creation.");
}
+ return createVirtualDevice(token, attributionSource, associationInfo, params,
+ activityListener, soundEffectListener);
+ }
+
+ private IVirtualDevice createVirtualDevice(
+ IBinder token,
+ AttributionSource attributionSource,
+ AssociationInfo associationInfo,
+ @NonNull VirtualDeviceParams params,
+ @Nullable IVirtualDeviceActivityListener activityListener,
+ @Nullable IVirtualDeviceSoundEffectListener soundEffectListener) {
+ createVirtualDevice_enforcePermission();
+ attributionSource.enforceCallingUid();
+
+ final String packageName = attributionSource.getPackageName();
+ if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
+ throw new SecurityException(
+ "Package name " + packageName + " does not belong to calling uid "
+ + getCallingUid());
+ }
Objects.requireNonNull(params);
- Objects.requireNonNull(activityListener);
- Objects.requireNonNull(soundEffectListener);
final UserHandle userHandle = getCallingUserHandle();
final CameraAccessController cameraAccessController =
@@ -724,6 +742,21 @@
private final ArraySet<Integer> mAllUidsOnVirtualDevice = new ArraySet<>();
@Override
+ public @NonNull VirtualDeviceManager.VirtualDevice createVirtualDevice(
+ @NonNull VirtualDeviceParams params) {
+ Objects.requireNonNull(params, "params must not be null");
+ Objects.requireNonNull(params.getName(), "virtual device name must not be null");
+ IVirtualDevice virtualDevice = mImpl.createVirtualDevice(
+ new Binder(),
+ getContext().getAttributionSource(),
+ /* associationInfo= */ null,
+ params,
+ /* activityListener= */ null,
+ /* soundEffectListener= */ null);
+ return new VirtualDeviceManager.VirtualDevice(mImpl, getContext(), virtualDevice);
+ }
+
+ @Override
public int getDeviceOwnerUid(int deviceId) {
VirtualDeviceImpl virtualDevice;
synchronized (mVirtualDeviceManagerLock) {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index d9962c7..1cd20ed 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -47,7 +47,7 @@
],
tools: ["protologtool"],
cmd: "$(location protologtool) transform-protolog-calls " +
- "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+ "--protolog-class com.android.internal.protolog.ProtoLog " +
"--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
"--loggroups-jar $(location :protolog-groups) " +
"--viewer-config-file-path /etc/core.protolog.pb " +
@@ -66,7 +66,7 @@
],
tools: ["protologtool"],
cmd: "$(location protologtool) generate-viewer-config " +
- "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+ "--protolog-class com.android.internal.protolog.ProtoLog " +
"--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
"--loggroups-jar $(location :protolog-groups) " +
"--viewer-config-type json " +
@@ -83,7 +83,7 @@
],
tools: ["protologtool"],
cmd: "$(location protologtool) generate-viewer-config " +
- "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+ "--protolog-class com.android.internal.protolog.ProtoLog " +
"--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
"--loggroups-jar $(location :protolog-groups) " +
"--viewer-config-type proto " +
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 189b2495..dfd148d 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -58,7 +58,6 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -493,14 +492,6 @@
private static void executeRescueLevelInternalOld(Context context, int level, @Nullable
String failedPackage) throws Exception {
-
- // Note: DeviceConfig reset is disabled currently and would be enabled using the flag,
- // after we have figured out a way to reset flags without interfering with trunk
- // development. TODO: b/287618292 For enabling flag resets.
- if (!Flags.allowRescuePartyFlagResets() && level <= LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS) {
- return;
- }
-
CrashRecoveryStatsLog.write(CrashRecoveryStatsLog.RESCUE_PARTY_RESET_REPORTED,
level, levelToString(level));
// Try our best to reset all settings possible, and once finished
@@ -508,43 +499,10 @@
Exception res = null;
switch (level) {
case LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
- try {
- resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
- level);
- } catch (Exception e) {
- res = e;
- }
- try {
- resetDeviceConfig(context, /*isScoped=*/true, failedPackage);
- } catch (Exception e) {
- res = e;
- }
break;
case LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
- try {
- resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES,
- level);
- } catch (Exception e) {
- res = e;
- }
- try {
- resetDeviceConfig(context, /*isScoped=*/true, failedPackage);
- } catch (Exception e) {
- res = e;
- }
break;
case LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
- try {
- resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS,
- level);
- } catch (Exception e) {
- res = e;
- }
- try {
- resetDeviceConfig(context, /*isScoped=*/false, failedPackage);
- } catch (Exception e) {
- res = e;
- }
break;
case LEVEL_WARM_REBOOT:
executeWarmReboot(context, level, failedPackage);
@@ -572,16 +530,8 @@
level, levelToString(level));
switch (level) {
case RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET:
- // Enable deviceConfig reset behind flag
- if (Flags.allowRescuePartyFlagResets()) {
- resetDeviceConfig(context, /*isScoped=*/true, failedPackage);
- }
break;
case RESCUE_LEVEL_ALL_DEVICE_CONFIG_RESET:
- // Enable deviceConfig reset behind flag
- if (Flags.allowRescuePartyFlagResets()) {
- resetDeviceConfig(context, /*isScoped=*/false, failedPackage);
- }
break;
case RESCUE_LEVEL_WARM_REBOOT:
executeWarmReboot(context, level, failedPackage);
@@ -732,61 +682,6 @@
}
}
- private static void resetDeviceConfig(Context context, boolean isScoped,
- @Nullable String failedPackage) throws Exception {
- final ContentResolver resolver = context.getContentResolver();
- try {
- if (!isScoped || failedPackage == null) {
- resetAllAffectedNamespaces(context);
- } else {
- performScopedReset(context, failedPackage);
- }
- } catch (Exception e) {
- throw new RuntimeException("Failed to reset config settings", e);
- }
- }
-
- private static void resetAllAffectedNamespaces(Context context) {
- RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
- Set<String> allAffectedNamespaces = rescuePartyObserver.getAllAffectedNamespaceSet();
-
- Slog.w(TAG,
- "Performing reset for all affected namespaces: "
- + Arrays.toString(allAffectedNamespaces.toArray()));
- Iterator<String> it = allAffectedNamespaces.iterator();
- while (it.hasNext()) {
- String namespace = it.next();
- // Don't let RescueParty reset the namespace for RescueParty switches.
- if (NAMESPACE_CONFIGURATION.equals(namespace)) {
- continue;
- }
- DeviceConfig.resetToDefaults(DEVICE_CONFIG_RESET_MODE, namespace);
- }
- }
-
- private static void performScopedReset(Context context, @NonNull String failedPackage) {
- RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
- Set<String> affectedNamespaces = rescuePartyObserver.getAffectedNamespaceSet(
- failedPackage);
- // If we can't find namespaces affected for current package,
- // skip this round of reset.
- if (affectedNamespaces != null) {
- Slog.w(TAG,
- "Performing scoped reset for package: " + failedPackage
- + ", affected namespaces: "
- + Arrays.toString(affectedNamespaces.toArray()));
- Iterator<String> it = affectedNamespaces.iterator();
- while (it.hasNext()) {
- String namespace = it.next();
- // Don't let RescueParty reset the namespace for RescueParty switches.
- if (NAMESPACE_CONFIGURATION.equals(namespace)) {
- continue;
- }
- DeviceConfig.resetToDefaults(DEVICE_CONFIG_RESET_MODE, namespace);
- }
- }
- }
-
/**
* Handle mitigation action for package failures. This observer will be register to Package
* Watchdog and will receive calls about package failures. This observer is persistent so it
diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java
index 3d3535d..73d8384 100644
--- a/services/core/java/com/android/server/SystemServerInitThreadPool.java
+++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java
@@ -197,8 +197,8 @@
/* processCpuTracker= */null, /* lastPids= */null,
CompletableFuture.completedFuture(Watchdog.getInterestingNativePids()),
/* logExceptionCreatingFile= */null, /* subject= */null,
- /* criticalEventSection= */null, Runnable::run,
- /* latencyTracker= */null);
+ /* criticalEventSection= */null, /* extraHeaders= */ null,
+ Runnable::run, /* latencyTracker= */null);
}
@Override
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 72a55dbe..21947ba 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -74,6 +74,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -991,6 +992,9 @@
FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED, subject);
}
+ final LinkedHashMap headersMap =
+ com.android.server.am.Flags.enableDropboxWatchdogHeaders()
+ ? new LinkedHashMap<>(Collections.singletonMap("Watchdog-Type", dropboxTag)) : null;
long anrTime = SystemClock.uptimeMillis();
StringBuilder report = new StringBuilder();
report.append(ResourcePressureUtil.currentPsiState());
@@ -998,8 +1002,9 @@
StringWriter tracesFileException = new StringWriter();
final File stack = StackTracesDumpHelper.dumpStackTraces(
pids, processCpuTracker, new SparseBooleanArray(),
- CompletableFuture.completedFuture(getInterestingNativePids()), tracesFileException,
- subject, criticalEvents, Runnable::run, /* latencyTracker= */null);
+ CompletableFuture.completedFuture(getInterestingNativePids()),
+ tracesFileException, subject, criticalEvents, headersMap,
+ Runnable::run, /* latencyTracker= */null);
// Give some extra time to make sure the stack traces get written.
// The system's been hanging for a whlie, another second or two won't hurt much.
SystemClock.sleep(5000);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index df35ff3..25fb729 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -429,7 +429,7 @@
import com.android.internal.os.Zygote;
import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
import com.android.internal.policy.AttributeCache;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
@@ -5481,8 +5481,13 @@
private boolean isHomeLaunchDelayable() {
// This feature is disabled on Auto since it seems to add an unacceptably long boot delay
// without even solving the underlying issue (it merely hits the timeout).
- return enableHomeDelay() &&
- !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ // This feature is disabled on TV since the ThemeOverlayController is currently not present
+ // and therefore we do not want to wait unnecessarily.
+ // This feature is currently disabled in WearOS to avoid extreme boot regressions
+ return enableHomeDelay()
+ && !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+ && !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+ && !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
}
final void ensureBootCompleted() {
@@ -10238,6 +10243,19 @@
addStartInfoTimestampInternal(key, timestampNs, userId, callingUid);
}
+ @Override
+ public void reportStartInfoViewTimestamps(long renderThreadDrawStartTimeNs,
+ long framePresentedTimeNs) {
+ int callingUid = Binder.getCallingUid();
+ int userId = UserHandle.getUserId(callingUid);
+ addStartInfoTimestampInternal(
+ ApplicationStartInfo.START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME,
+ renderThreadDrawStartTimeNs, userId, callingUid);
+ addStartInfoTimestampInternal(
+ ApplicationStartInfo.START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE,
+ framePresentedTimeNs, userId, callingUid);
+ }
+
private void addStartInfoTimestampInternal(int key, long timestampNs, int userId, int uid) {
mProcessList.getAppStartInfoTracker().addTimestampToStart(
Settings.getPackageNameForUid(mContext, uid),
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 3042b2a..4a7ad31 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -1195,21 +1195,8 @@
// Records are sorted newest to oldest, grab record at index 0.
ApplicationStartInfo startInfo = mInfos.get(0);
- int startupState = startInfo.getStartupState();
- // If startup state is error then don't accept any further timestamps.
- if (startupState == ApplicationStartInfo.STARTUP_STATE_ERROR) {
- if (DEBUG) Slog.d(TAG, "Startup state is error, not accepting new timestamps.");
- return;
- }
-
- // If startup state is first frame drawn then only accept fully drawn timestamp.
- if (startupState == ApplicationStartInfo.STARTUP_STATE_FIRST_FRAME_DRAWN
- && key != ApplicationStartInfo.START_TIMESTAMP_FULLY_DRAWN) {
- if (DEBUG) {
- Slog.d(TAG, "Startup state is first frame drawn and timestamp is not fully "
- + "drawn, not accepting new timestamps.");
- }
+ if (!isAddTimestampAllowed(startInfo, key, timestampNs)) {
return;
}
@@ -1222,6 +1209,55 @@
}
}
+ private boolean isAddTimestampAllowed(ApplicationStartInfo startInfo, int key,
+ long timestampNs) {
+ int startupState = startInfo.getStartupState();
+
+ // If startup state is error then don't accept any further timestamps.
+ if (startupState == ApplicationStartInfo.STARTUP_STATE_ERROR) {
+ if (DEBUG) Slog.d(TAG, "Startup state is error, not accepting new timestamps.");
+ return false;
+ }
+
+ Map<Integer, Long> timestamps = startInfo.getStartupTimestamps();
+
+ if (startupState == ApplicationStartInfo.STARTUP_STATE_FIRST_FRAME_DRAWN) {
+ switch (key) {
+ case ApplicationStartInfo.START_TIMESTAMP_FULLY_DRAWN:
+ // Allowed, continue to confirm it's not already added.
+ break;
+ case ApplicationStartInfo.START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME:
+ Long firstFrameTimeNs = timestamps
+ .get(ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME);
+ if (firstFrameTimeNs == null) {
+ // This should never happen. State can't be first frame drawn if first
+ // frame timestamp was not provided.
+ return false;
+ }
+
+ if (timestampNs > firstFrameTimeNs) {
+ // Initial renderthread frame has to occur before first frame.
+ return false;
+ }
+
+ // Allowed, continue to confirm it's not already added.
+ break;
+ case ApplicationStartInfo.START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE:
+ // Allowed, continue to confirm it's not already added.
+ break;
+ default:
+ return false;
+ }
+ }
+
+ if (timestamps.get(key) != null) {
+ // Timestamp should not occur more than once for a given start.
+ return false;
+ }
+
+ return true;
+ }
+
@GuardedBy("mLock")
void dumpLocked(PrintWriter pw, String prefix, SimpleDateFormat sdf) {
if (mMonitoringModeEnabled) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 0c14a1c..00183ac 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -848,6 +848,7 @@
}
private void syncStats(String reason, int flags) {
+ mStats.collectPowerStatsSamples();
awaitUninterruptibly(mWorker.scheduleSync(reason, flags));
}
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index d4d4965..ba4b71c 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -60,7 +60,6 @@
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
import com.android.server.wm.WindowProcessController;
-import com.android.server.utils.AnrTimer;
import java.io.File;
import java.io.PrintWriter;
@@ -69,6 +68,7 @@
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -429,7 +429,7 @@
}
}
// Build memory headers for the ANRing process.
- String memoryHeaders = buildMemoryHeadersFor(pid);
+ LinkedHashMap<String, String> memoryHeaders = buildMemoryHeadersFor(pid);
// Get critical event log before logging the ANR so that it doesn't occur in the log.
latencyTracker.criticalEventLogStarted();
@@ -753,7 +753,7 @@
resolver.getUserId()) != 0;
}
- private @Nullable String buildMemoryHeadersFor(int pid) {
+ private @Nullable LinkedHashMap<String, String> buildMemoryHeadersFor(int pid) {
if (pid <= 0) {
Slog.i(TAG, "Memory header requested with invalid pid: " + pid);
return null;
@@ -764,15 +764,13 @@
return null;
}
- StringBuilder memoryHeaders = new StringBuilder();
- memoryHeaders.append("RssHwmKb: ")
- .append(snapshot.rssHighWaterMarkInKilobytes)
- .append("\n");
- memoryHeaders.append("RssKb: ").append(snapshot.rssInKilobytes).append("\n");
- memoryHeaders.append("RssAnonKb: ").append(snapshot.anonRssInKilobytes).append("\n");
- memoryHeaders.append("RssShmemKb: ").append(snapshot.rssShmemKilobytes).append("\n");
- memoryHeaders.append("VmSwapKb: ").append(snapshot.swapInKilobytes).append("\n");
- return memoryHeaders.toString();
+ LinkedHashMap<String, String> memoryHeaders = new LinkedHashMap<>();
+ memoryHeaders.put("RssHwmKb", Integer.toString(snapshot.rssHighWaterMarkInKilobytes));
+ memoryHeaders.put("RssKb", Integer.toString(snapshot.rssInKilobytes));
+ memoryHeaders.put("RssAnonKb", Integer.toString(snapshot.anonRssInKilobytes));
+ memoryHeaders.put("RssShmemKb", Integer.toString(snapshot.rssShmemKilobytes));
+ memoryHeaders.put("VmSwapKb", Integer.toString(snapshot.swapInKilobytes));
+ return memoryHeaders;
}
/**
* Unless configured otherwise, swallow ANRs in background processes & kill the process.
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index c094724..779aabe 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -855,8 +855,8 @@
Slog.i(TAG, "Failed to connect to lmkd, retry after " +
LMKD_RECONNECT_DELAY_MS + " ms");
// retry after LMKD_RECONNECT_DELAY_MS
- sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
- KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
+ sendMessageDelayed(obtainMessage(
+ LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
}
break;
default:
@@ -5559,8 +5559,9 @@
void noteAppKill(final ProcessRecord app, final @Reason int reason,
final @SubReason int subReason, final String msg) {
if (DEBUG_PROCESSES) {
- Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
- + ", sub-reason: " + subReason + ", message: " + msg);
+ Slog.i(TAG, "note: " + app + " is being killed, reason: "
+ + ApplicationExitInfo.reasonCodeToString(reason) + ", sub-reason: "
+ + ApplicationExitInfo.subreasonToString(subReason) + ", message: " + msg);
}
if (app.getPid() > 0 && !app.isolated && app.getDeathRecipient() != null) {
// We are killing it, put it into the dying process list.
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index cbea7aa..932b9c0 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -136,6 +136,7 @@
static final String[] sDeviceConfigAconfigScopes = new String[] {
"accessibility",
"android_core_networking",
+ "android_sdk",
"android_stylus",
"aoc",
"app_widgets",
diff --git a/services/core/java/com/android/server/am/StackTracesDumpHelper.java b/services/core/java/com/android/server/am/StackTracesDumpHelper.java
index c1374e1..2021ba4 100644
--- a/services/core/java/com/android/server/am/StackTracesDumpHelper.java
+++ b/services/core/java/com/android/server/am/StackTracesDumpHelper.java
@@ -47,6 +47,8 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
@@ -100,15 +102,17 @@
/**
* @param subject the subject of the dumped traces
* @param criticalEventSection the critical event log, passed as a string
+ * @param extraHeaders Optional, Extra headers added by the dumping method
*/
public static File dumpStackTraces(ArrayList<Integer> firstPids,
ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
- String subject, String criticalEventSection, @NonNull Executor auxiliaryTaskExecutor,
+ String subject, String criticalEventSection,
+ LinkedHashMap<String, String> extraHeaders, @NonNull Executor auxiliaryTaskExecutor,
AnrLatencyTracker latencyTracker) {
return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
logExceptionCreatingFile, null, subject, criticalEventSection,
- /* memoryHeaders= */ null, auxiliaryTaskExecutor, null, latencyTracker);
+ extraHeaders, auxiliaryTaskExecutor, null, latencyTracker);
}
/**
@@ -119,7 +123,7 @@
ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
AtomicLong firstPidEndOffset, String subject, String criticalEventSection,
- String memoryHeaders, @NonNull Executor auxiliaryTaskExecutor,
+ LinkedHashMap<String, String> extraHeaders, @NonNull Executor auxiliaryTaskExecutor,
Future<File> firstPidFilePromise, AnrLatencyTracker latencyTracker) {
try {
@@ -159,11 +163,12 @@
}
return null;
}
+ boolean extraHeadersExist = extraHeaders != null && !extraHeaders.isEmpty();
- if (subject != null || criticalEventSection != null || memoryHeaders != null) {
+ if (subject != null || criticalEventSection != null || extraHeadersExist) {
appendtoANRFile(tracesFile.getAbsolutePath(),
(subject != null ? "Subject: " + subject + "\n" : "")
- + (memoryHeaders != null ? memoryHeaders + "\n\n" : "")
+ + (extraHeadersExist ? stringifyHeaders(extraHeaders) + "\n\n" : "")
+ (criticalEventSection != null ? criticalEventSection : ""));
}
@@ -614,4 +619,15 @@
return pids;
}
+ private static String stringifyHeaders(@NonNull LinkedHashMap<String, String> headers) {
+ StringBuilder headersString = new StringBuilder();
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
+ headersString.append(entry.getKey())
+ .append(": ")
+ .append(entry.getValue())
+ .append("\n");
+ }
+ return headersString.toString();
+ }
+
}
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 0dfa330..9b380ff 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -167,4 +167,12 @@
description: "Allow logcat collection on synchronous dropbox collection"
bug: "324222683"
is_fixed_read_only: true
-}
\ No newline at end of file
+}
+
+flag {
+ name: "enable_dropbox_watchdog_headers"
+ namespace: "dropbox"
+ description: "Add watchdog-specific dropbox headers"
+ bug: "330682397"
+ is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index b1a12f7..5d83ad6 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -26,6 +26,7 @@
import static android.app.AppOpsManager.FILTER_BY_UID;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_COARSE_LOCATION;
+import static android.app.AppOpsManager.OP_EMERGENCY_LOCATION;
import static android.app.AppOpsManager.OP_FINE_LOCATION;
import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_FLAG_SELF;
@@ -135,9 +136,10 @@
private static final String PROPERTY_DISCRETE_FLAGS = "discrete_history_op_flags";
private static final String PROPERTY_DISCRETE_OPS_LIST = "discrete_history_ops_cslist";
private static final String DEFAULT_DISCRETE_OPS = OP_FINE_LOCATION + "," + OP_COARSE_LOCATION
- + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + "," + OP_PHONE_CALL_MICROPHONE + ","
- + OP_PHONE_CALL_CAMERA + "," + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO + ","
- + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO + "," + OP_RESERVED_FOR_TESTING;
+ + "," + OP_EMERGENCY_LOCATION + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + ","
+ + OP_PHONE_CALL_MICROPHONE + "," + OP_PHONE_CALL_CAMERA + ","
+ + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO + "," + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO
+ + "," + OP_RESERVED_FOR_TESTING;
private static final long DEFAULT_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(7).toMillis();
private static final long MAXIMUM_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(30).toMillis();
private static final long DEFAULT_DISCRETE_HISTORY_QUANTIZATION =
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 27fda15..8de1552 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -51,6 +51,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -374,6 +375,16 @@
deviceInfo.mScoAudioMode, deviceInfo.mIsPrivileged, deviceInfo.mEventSource);
}
+ /**
+ * Indicates if a Bluetooth SCO activation request owner is controlling
+ * the SCO audio state itself or not.
+ * @param uid the UI of the SOC request owner app
+ * @return true if we should control SCO audio state, false otherwise
+ */
+ private boolean shouldStartScoForUid(int uid) {
+ return !(uid == Process.BLUETOOTH_UID || uid == Process.PHONE_UID);
+ }
+
@GuardedBy("mDeviceStateLock")
/*package*/ void setCommunicationRouteForClient(
IBinder cb, int uid, AudioDeviceAttributes device,
@@ -388,7 +399,7 @@
+ " device: " + device + " isPrivileged: " + isPrivileged
+ " from API: " + eventSource)).printLog(TAG));
- final boolean wasBtScoRequested = isBluetoothScoRequested();
+ final int previousBtScoRequesterUid = bluetoothScoRequestOwnerUid();
CommunicationRouteClient client;
// Save previous client route in case of failure to start BT SCO audio
@@ -412,8 +423,40 @@
if (client == null) {
return;
}
- if (!mScoManagedByAudio) {
- boolean isBtScoRequested = isBluetoothScoRequested();
+ final int btScoRequesterUid = bluetoothScoRequestOwnerUid();
+ final boolean isBtScoRequested = btScoRequesterUid != -1;
+ final boolean wasBtScoRequested = previousBtScoRequesterUid != -1;
+
+ if (mScoManagedByAudio) {
+ if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive()
+ || !mBtHelper.isBluetoothScoRequestedInternally())) {
+ boolean scoStarted = false;
+ if (shouldStartScoForUid(btScoRequesterUid)) {
+ scoStarted = mBtHelper.startBluetoothSco(scoAudioMode, eventSource);
+ if (!scoStarted) {
+ Log.w(TAG, "setCommunicationRouteForClient: "
+ + "failure to start BT SCO for uid: " + uid);
+ // clean up or restore previous client selection
+ if (prevClientDevice != null) {
+ addCommunicationRouteClient(cb, uid, prevClientDevice, prevPrivileged);
+ } else {
+ removeCommunicationRouteClient(cb, true);
+ }
+ postBroadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+ }
+ } else {
+ scoStarted = true;
+ }
+ if (scoStarted) {
+ setBluetoothScoOn(true, "setCommunicationRouteForClient");
+ }
+ } else if (!isBtScoRequested && wasBtScoRequested) {
+ if (shouldStartScoForUid(previousBtScoRequesterUid)) {
+ mBtHelper.stopBluetoothSco(eventSource);
+ }
+ setBluetoothScoOn(false, "setCommunicationRouteForClient");
+ }
+ } else {
if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive()
|| !mBtHelper.isBluetoothScoRequestedInternally())) {
if (!mBtHelper.startBluetoothSco(scoAudioMode, eventSource)) {
@@ -431,19 +474,10 @@
mBtHelper.stopBluetoothSco(eventSource);
}
}
- // In BT classic for communication, the device changes from a2dp to sco device, but for
- // LE Audio it stays the same and we must trigger the proper stream volume alignment, if
- // LE Audio communication device is activated after the audio system has already switched to
- // MODE_IN_CALL mode.
- if (isBluetoothLeAudioRequested() && device != null) {
- final int streamType = mAudioService.getBluetoothContextualVolumeStream();
- final int leAudioVolIndex = getVssVolumeForDevice(streamType, device.getInternalType());
- final int leAudioMaxVolIndex = getMaxVssVolumeForStream(streamType);
- if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "setCommunicationRouteForClient restoring LE Audio device volume lvl.");
- }
- postSetLeAudioVolumeIndex(leAudioVolIndex, leAudioMaxVolIndex, streamType);
- }
+ // In BT classic for communication, the device changes from a2dp to sco device,
+ // but for LE Audio or Hearing Aid it stays the same and we must trigger the proper
+ // stream volume alignment.
+ mAudioService.postUpdateContextualVolumes();
updateCommunicationRoute(eventSource);
}
@@ -575,12 +609,12 @@
@GuardedBy("mDeviceStateLock")
/*package*/ void updateCommunicationRouteClientState(
CommunicationRouteClient client, boolean wasActive) {
- boolean wasBtScoRequested = isBluetoothScoRequested();
+ int btScoRequesterUid = bluetoothScoRequestOwnerUid();
client.setPlaybackActive(mAudioService.isPlaybackActiveForUid(client.getUid()));
client.setRecordingActive(mAudioService.isRecordingActiveForUid(client.getUid()));
if (wasActive != client.isActive()) {
postUpdateCommunicationRouteClient(
- wasBtScoRequested, "updateCommunicationRouteClientState");
+ btScoRequesterUid, "updateCommunicationRouteClientState");
}
}
@@ -763,6 +797,22 @@
}
/**
+ * Helper method on top of isBluetoothScoRequested() returning the UID of the
+ * BT SCO route request owner of -1 if SCO is not requested.
+ * @return the UID of the BT SCO route request owner of -1 if SCO is not requested.
+ */
+ @GuardedBy("mDeviceStateLock")
+ /*package*/ int bluetoothScoRequestOwnerUid() {
+ if (!isBluetoothScoRequested()) {
+ return -1;
+ }
+ CommunicationRouteClient crc = topCommunicationRouteClient();
+ if (crc == null) {
+ return -1;
+ }
+ return crc.getUid();
+ }
+ /**
* Helper method on top of isDeviceRequestedForCommunication() indicating if
* Bluetooth LE Audio communication device is currently requested or not.
* @return true if Bluetooth LE Audio device is requested, false otherwise.
@@ -1148,15 +1198,18 @@
}
}
+ @GuardedBy("mDeviceStateLock")
/*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
synchronized (mBluetoothAudioStateLock) {
- boolean isBtScoRequested = isBluetoothScoRequested();
+ int btScoRequesterUId = bluetoothScoRequestOwnerUid();
Log.i(TAG, "setBluetoothScoOn: " + on + ", mBluetoothScoOn: "
- + mBluetoothScoOn + ", isBtScoRequested: " + isBtScoRequested
+ + mBluetoothScoOn + ", btScoRequesterUId: " + btScoRequesterUId
+ ", from: " + eventSource);
mBluetoothScoOn = on;
updateAudioHalBluetoothState();
- postUpdateCommunicationRouteClient(isBtScoRequested, eventSource);
+ if (!mScoManagedByAudio) {
+ postUpdateCommunicationRouteClient(btScoRequesterUId, eventSource);
+ }
}
}
@@ -1510,9 +1563,9 @@
}
/*package*/ void postUpdateCommunicationRouteClient(
- boolean wasBtScoRequested, String eventSource) {
+ int btScoRequesterUid, String eventSource) {
sendILMsgNoDelay(MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE,
- wasBtScoRequested ? 1 : 0, eventSource);
+ btScoRequesterUid, eventSource);
}
/*package*/ void postSetCommunicationDeviceForClient(CommunicationDeviceInfo info) {
@@ -1865,7 +1918,7 @@
|| btInfo.mProfile == BluetoothProfile.HEARING_AID
|| (mScoManagedByAudio
&& btInfo.mProfile == BluetoothProfile.HEADSET)) {
- onUpdateCommunicationRouteClient(isBluetoothScoRequested(),
+ onUpdateCommunicationRouteClient(bluetoothScoRequestOwnerUid(),
"setBluetoothActiveDevice");
}
}
@@ -1927,11 +1980,11 @@
case MSG_I_SET_MODE_OWNER:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
- boolean wasBtScoRequested = isBluetoothScoRequested();
+ int btScoRequesterUid = bluetoothScoRequestOwnerUid();
mAudioModeOwner = (AudioModeInfo) msg.obj;
if (mAudioModeOwner.mMode != AudioSystem.MODE_RINGTONE) {
onUpdateCommunicationRouteClient(
- wasBtScoRequested, "setNewModeOwner");
+ btScoRequesterUid, "setNewModeOwner");
}
}
}
@@ -1958,7 +2011,7 @@
case MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
- onUpdateCommunicationRouteClient(msg.arg1 == 1, (String) msg.obj);
+ onUpdateCommunicationRouteClient(msg.arg1, (String) msg.obj);
}
}
break;
@@ -2457,7 +2510,7 @@
@Nullable private AudioDeviceAttributes preferredCommunicationDevice() {
boolean btSCoOn = mBtHelper.isBluetoothScoOn();
synchronized (mBluetoothAudioStateLock) {
- btSCoOn = btSCoOn && mBluetoothScoOn;
+ btSCoOn = (btSCoOn || mScoManagedByAudio) && mBluetoothScoOn;
}
if (btSCoOn) {
@@ -2522,18 +2575,28 @@
*/
// @GuardedBy("mSetModeLock")
@GuardedBy("mDeviceStateLock")
- private void onUpdateCommunicationRouteClient(boolean wasBtScoRequested, String eventSource) {
+ private void onUpdateCommunicationRouteClient(
+ int previousBtScoRequesterUid, String eventSource) {
CommunicationRouteClient crc = topCommunicationRouteClient();
if (AudioService.DEBUG_COMM_RTE) {
Log.v(TAG, "onUpdateCommunicationRouteClient, crc: " + crc
- + " wasBtScoRequested: " + wasBtScoRequested + " eventSource: " + eventSource);
+ + " previousBtScoRequesterUid: " + previousBtScoRequesterUid
+ + " eventSource: " + eventSource);
}
if (crc != null) {
setCommunicationRouteForClient(crc.getBinder(), crc.getUid(), crc.getDevice(),
BtHelper.SCO_MODE_UNDEFINED, crc.isPrivileged(), eventSource);
} else {
- if (!mScoManagedByAudio && !isBluetoothScoRequested() && wasBtScoRequested) {
- mBtHelper.stopBluetoothSco(eventSource);
+ boolean wasScoRequested = previousBtScoRequesterUid != -1;
+ if (!isBluetoothScoRequested() && wasScoRequested) {
+ if (mScoManagedByAudio) {
+ if (shouldStartScoForUid(previousBtScoRequesterUid)) {
+ mBtHelper.stopBluetoothSco(eventSource);
+ }
+ setBluetoothScoOn(false, eventSource);
+ } else {
+ mBtHelper.stopBluetoothSco(eventSource);
+ }
}
updateCommunicationRoute(eventSource);
}
@@ -2793,12 +2856,13 @@
return mDeviceInventory.getImmutableDeviceInventory();
}
- void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
- mDeviceInventory.addOrUpdateDeviceSAStateInInventory(deviceState);
+ void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState, boolean syncInventory) {
+ mDeviceInventory.addOrUpdateDeviceSAStateInInventory(deviceState, syncInventory);
}
- void addOrUpdateBtAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
- mDeviceInventory.addOrUpdateAudioDeviceCategoryInInventory(deviceState);
+ void addOrUpdateBtAudioDeviceCategoryInInventory(
+ AdiDeviceState deviceState, boolean syncInventory) {
+ mDeviceInventory.addOrUpdateAudioDeviceCategoryInInventory(deviceState, syncInventory);
}
@Nullable
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index ba7aee0..02aa6f5 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -135,9 +135,10 @@
* AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
* @param deviceState the device to update
*/
- void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
+ void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState, boolean syncInventory) {
synchronized (mDeviceInventoryLock) {
- mDeviceInventory.merge(deviceState.getDeviceId(), deviceState, (oldState, newState) -> {
+ mDeviceInventory.merge(deviceState.getDeviceId(), deviceState,
+ (oldState, newState) -> {
oldState.setHasHeadTracker(newState.hasHeadTracker());
oldState.setHeadTrackerEnabled(newState.isHeadTrackerEnabled());
oldState.setSAEnabled(newState.isSAEnabled());
@@ -145,7 +146,9 @@
});
checkDeviceInventorySize_l();
}
- mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+ if (syncInventory) {
+ mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+ }
}
/**
@@ -196,7 +199,8 @@
* AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
* @param deviceState the device to update
*/
- void addOrUpdateAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
+ void addOrUpdateAudioDeviceCategoryInInventory(
+ AdiDeviceState deviceState, boolean syncInventory) {
AtomicBoolean updatedCategory = new AtomicBoolean(false);
synchronized (mDeviceInventoryLock) {
if (automaticBtDeviceType()) {
@@ -218,7 +222,9 @@
if (updatedCategory.get()) {
mDeviceBroker.postUpdatedAdiDeviceState(deviceState, false /*initSA*/);
}
- mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+ if (syncInventory) {
+ mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+ }
}
void addAudioDeviceWithCategoryInInventoryIfNeeded(@NonNull String address,
@@ -235,14 +241,14 @@
boolean bleCategoryFound = false;
AdiDeviceState deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLE_HEADSET);
if (deviceState != null) {
- addOrUpdateAudioDeviceCategoryInInventory(deviceState);
+ addOrUpdateAudioDeviceCategoryInInventory(deviceState, true /*syncInventory*/);
btCategory = deviceState.getAudioDeviceCategory();
bleCategoryFound = true;
}
deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLUETOOTH_A2DP);
if (deviceState != null) {
- addOrUpdateAudioDeviceCategoryInInventory(deviceState);
+ addOrUpdateAudioDeviceCategoryInInventory(deviceState, true /*syncInventory*/);
int a2dpCategory = deviceState.getAudioDeviceCategory();
if (bleCategoryFound && a2dpCategory != btCategory) {
Log.w(TAG, "Found different audio device category for A2DP and BLE profiles with "
@@ -269,23 +275,43 @@
}
/**
- * synchronize AdiDeviceState for LE devices in the same group
+ * Synchronize AdiDeviceState for LE devices in the same group
+ * or BT classic devices with the same address.
+ * @param updatedDevice the device state to synchronize or null.
+ * Called with null once after the device inventory and spatializer helper
+ * have been initialized to resync all devices.
*/
void onSynchronizeAdiDevicesInInventory(AdiDeviceState updatedDevice) {
synchronized (mDevicesLock) {
synchronized (mDeviceInventoryLock) {
- boolean found = false;
- found |= synchronizeBleDeviceInInventory(updatedDevice);
- if (automaticBtDeviceType()) {
- found |= synchronizeDeviceProfilesInInventory(updatedDevice);
- }
- if (found) {
- mDeviceBroker.postPersistAudioDeviceSettings();
+ if (updatedDevice != null) {
+ onSynchronizeAdiDeviceInInventory_l(updatedDevice);
+ } else {
+ for (AdiDeviceState ads : mDeviceInventory.values()) {
+ onSynchronizeAdiDeviceInInventory_l(ads);
+ }
}
}
}
}
+ /**
+ * Synchronize AdiDeviceState for LE devices in the same group
+ * or BT classic devices with the same address.
+ * @param updatedDevice the device state to synchronize.
+ */
+ @GuardedBy({"mDevicesLock", "mDeviceInventoryLock"})
+ void onSynchronizeAdiDeviceInInventory_l(AdiDeviceState updatedDevice) {
+ boolean found = false;
+ found |= synchronizeBleDeviceInInventory(updatedDevice);
+ if (automaticBtDeviceType()) {
+ found |= synchronizeDeviceProfilesInInventory(updatedDevice);
+ }
+ if (found) {
+ mDeviceBroker.postPersistAudioDeviceSettings();
+ }
+ }
+
@GuardedBy("mDeviceInventoryLock")
private void checkDeviceInventorySize_l() {
if (mDeviceInventory.size() > MAX_DEVICE_INVENTORY_ENTRIES) {
@@ -595,6 +621,9 @@
mDeviceName = TextUtils.emptyIfNull(deviceName);
mDeviceAddress = TextUtils.emptyIfNull(address);
mDeviceIdentityAddress = TextUtils.emptyIfNull(identityAddress);
+ if (mDeviceIdentityAddress.isEmpty()) {
+ mDeviceIdentityAddress = mDeviceAddress;
+ }
mDeviceCodecFormat = codecFormat;
mGroupId = groupId;
mPeerDeviceAddress = TextUtils.emptyIfNull(peerAddress);
@@ -2499,7 +2528,7 @@
mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/, eventSource);
AudioDeviceAttributes ada = new AudioDeviceAttributes(device, address, name);
- final int res = AudioSystem.setDeviceConnectionState(ada,
+ final int res = mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_AVAILABLE, codec);
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
@@ -2519,23 +2548,27 @@
new DeviceInfo(device, name, address,
btInfo.mDevice.getIdentityAddress(), codec,
groupId, peerAddress, peerIdentityAddress));
- mDeviceBroker.postAccessoryPlugMediaUnmute(device);
- setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
+ if (btInfo.mIsLeOutput) {
+ mDeviceBroker.postAccessoryPlugMediaUnmute(device);
+ setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
+ }
addAudioDeviceInInventoryIfNeeded(device, address, peerAddress,
BtHelper.getBtDeviceCategory(address), /*userDefined=*/false);
}
- if (streamType == AudioSystem.STREAM_DEFAULT) {
- // No need to update volume for input devices
- return;
- }
+ if (btInfo.mIsLeOutput) {
+ if (streamType == AudioSystem.STREAM_DEFAULT) {
+ // No need to update volume for input devices
+ return;
+ }
- final int leAudioVolIndex = (volumeIndex == -1)
- ? mDeviceBroker.getVssVolumeForDevice(streamType, device)
- : volumeIndex;
- final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
- mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
- mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
+ final int leAudioVolIndex = (volumeIndex == -1)
+ ? mDeviceBroker.getVssVolumeForDevice(streamType, device)
+ : volumeIndex;
+ final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
+ mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
+ mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
+ }
updateBluetoothPreferredModes_l(btInfo.mDevice /*connectedDevice*/);
}
@@ -2546,7 +2579,7 @@
AudioDeviceAttributes ada = null;
if (device != AudioSystem.DEVICE_NONE) {
ada = new AudioDeviceAttributes(device, address);
- final int res = AudioSystem.setDeviceConnectionState(ada,
+ final int res = mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
codec);
@@ -2951,8 +2984,8 @@
// Note if the device is not compatible with spatialization mode or the device
// type is not canonical, it will be ignored in {@link SpatializerHelper}.
if (devState != null) {
- addOrUpdateDeviceSAStateInInventory(devState);
- addOrUpdateAudioDeviceCategoryInInventory(devState);
+ addOrUpdateDeviceSAStateInInventory(devState, false /*syncInventory*/);
+ addOrUpdateAudioDeviceCategoryInInventory(devState, false /*syncInventory*/);
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
index 14eae8d..c5180af 100644
--- a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
+++ b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
@@ -36,6 +36,7 @@
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.IntArray;
+import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.media.permission.INativePermissionController;
@@ -61,6 +62,9 @@
static final String[] MONITORED_PERMS = new String[PermissionEnum.ENUM_SIZE];
+ static final byte[] HDS_PERMS = new byte[] {PermissionEnum.CAPTURE_AUDIO_HOTWORD,
+ PermissionEnum.CAPTURE_AUDIO_OUTPUT, PermissionEnum.RECORD_AUDIO};
+
static {
MONITORED_PERMS[PermissionEnum.RECORD_AUDIO] = RECORD_AUDIO;
MONITORED_PERMS[PermissionEnum.MODIFY_AUDIO_ROUTING] = MODIFY_AUDIO_ROUTING;
@@ -88,6 +92,7 @@
@GuardedBy("mLock")
private final Map<Integer, Set<String>> mPackageMap;
+
// Values are sorted
@GuardedBy("mLock")
private final int[][] mPermMap = new int[PermissionEnum.ENUM_SIZE][];
@@ -95,6 +100,9 @@
@GuardedBy("mLock")
private boolean mIsUpdateDeferred = true;
+ @GuardedBy("mLock")
+ private int mHdsUid = -1;
+
/**
* @param appInfos - PackageState for all apps on the device, used to populate init state
*/
@@ -124,7 +132,7 @@
try {
for (byte i = 0; i < PermissionEnum.ENUM_SIZE; i++) {
if (mIsUpdateDeferred) {
- mPermMap[i] = getUidsHoldingPerm(MONITORED_PERMS[i]);
+ mPermMap[i] = getUidsHoldingPerm(i);
}
mDest.populatePermissionState(i, mPermMap[i]);
}
@@ -184,7 +192,7 @@
}
try {
for (byte i = 0; i < PermissionEnum.ENUM_SIZE; i++) {
- var newPerms = getUidsHoldingPerm(MONITORED_PERMS[i]);
+ var newPerms = getUidsHoldingPerm(i);
if (!Arrays.equals(newPerms, mPermMap[i])) {
mPermMap[i] = newPerms;
mDest.populatePermissionState(i, newPerms);
@@ -199,6 +207,77 @@
}
}
+ public void setIsolatedServiceUid(int uid, int owningUid) {
+ synchronized (mLock) {
+ if (mHdsUid == uid) return;
+ var packageNameSet = mPackageMap.get(owningUid);
+ if (packageNameSet == null) return;
+ var packageName = packageNameSet.iterator().next();
+ onModifyPackageState(uid, packageName, /* isRemove= */ false);
+ // permissions
+ mHdsUid = uid;
+ if (mDest == null) {
+ mIsUpdateDeferred = true;
+ return;
+ }
+ try {
+ for (byte perm : HDS_PERMS) {
+ int[] newPerms = new int[mPermMap[perm].length + 1];
+ System.arraycopy(mPermMap[perm], 0, newPerms, 0, mPermMap[perm].length);
+ newPerms[newPerms.length - 1] = mHdsUid;
+ Arrays.sort(newPerms);
+ mPermMap[perm] = newPerms;
+ mDest.populatePermissionState(perm, newPerms);
+ }
+ } catch (RemoteException e) {
+ // We will re-init the state when the service comes back up
+ mDest = null;
+ // We didn't necessarily finish
+ mIsUpdateDeferred = true;
+ }
+ }
+ }
+
+ public void clearIsolatedServiceUid(int uid) {
+ synchronized (mLock) {
+ if (mHdsUid != uid) return;
+ var packageNameSet = mPackageMap.get(uid);
+ if (packageNameSet == null) return;
+ var packageName = packageNameSet.iterator().next();
+ onModifyPackageState(uid, packageName, /* isRemove= */ true);
+ // permissions
+ if (mDest == null) {
+ mIsUpdateDeferred = true;
+ return;
+ }
+ try {
+ for (byte perm : HDS_PERMS) {
+ int[] newPerms = new int[mPermMap[perm].length - 1];
+ int ind = Arrays.binarySearch(mPermMap[perm], uid);
+ if (ind < 0) continue;
+ System.arraycopy(mPermMap[perm], 0, newPerms, 0, ind);
+ System.arraycopy(mPermMap[perm], ind + 1, newPerms, ind,
+ mPermMap[perm].length - ind - 1);
+ mPermMap[perm] = newPerms;
+ mDest.populatePermissionState(perm, newPerms);
+ }
+ } catch (RemoteException e) {
+ // We will re-init the state when the service comes back up
+ mDest = null;
+ // We didn't necessarily finish
+ mIsUpdateDeferred = true;
+ }
+ mHdsUid = -1;
+ }
+ }
+
+ private boolean isSpecialHdsPermission(int perm) {
+ for (var hdsPerm : HDS_PERMS) {
+ if (perm == hdsPerm) return true;
+ }
+ return false;
+ }
+
/** Called when full syncing package state to audioserver. */
@GuardedBy("mLock")
private void resetNativePackageState() {
@@ -223,16 +302,19 @@
@GuardedBy("mLock")
/** Return all uids (not app-ids) which currently hold a given permission. Not app-op aware */
- private int[] getUidsHoldingPerm(String perm) {
+ private int[] getUidsHoldingPerm(int perm) {
IntArray acc = new IntArray();
for (int userId : mUserIdSupplier.get()) {
for (int appId : mPackageMap.keySet()) {
int uid = UserHandle.getUid(userId, appId);
- if (mPermissionPredicate.test(uid, perm)) {
+ if (mPermissionPredicate.test(uid, MONITORED_PERMS[perm])) {
acc.add(uid);
}
}
}
+ if (isSpecialHdsPermission(perm) && mHdsUid != -1) {
+ acc.add(mHdsUid);
+ }
var unwrapped = acc.toArray();
Arrays.sort(unwrapped);
return unwrapped;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index c89992d..6d9b4f5 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -461,6 +461,7 @@
private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
private static final int MSG_CONFIGURATION_CHANGED = 54;
private static final int MSG_BROADCAST_MASTER_MUTE = 55;
+ private static final int MSG_UPDATE_CONTEXTUAL_VOLUMES = 56;
/**
* Messages handled by the {@link SoundDoseHelper}, do not exceed
@@ -707,10 +708,14 @@
// Streams currently muted by ringer mode and dnd
protected static volatile int sRingerAndZenModeMutedStreams;
- /** Streams that can be muted. Do not resolve to aliases when checking.
+ /** Streams that can be muted by system. Do not resolve to aliases when checking.
* @see System#MUTE_STREAMS_AFFECTED */
private int mMuteAffectedStreams;
+ /** Streams that can be muted by user. Do not resolve to aliases when checking.
+ * @see System#MUTE_STREAMS_AFFECTED */
+ private int mUserMutableStreams;
+
@NonNull
private SoundEffectsHelper mSfxHelper;
@@ -836,7 +841,9 @@
// full scale, and volume control separately) and can be used for multiple use cases reflected
// by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
- Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
+ Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID,
+ AudioSystem.DEVICE_OUT_BLE_HEADSET,
+ AudioSystem.DEVICE_OUT_BLE_SPEAKER));
private final boolean mMonitorRotation;
@@ -2345,6 +2352,7 @@
mMuteAffectedStreams &= ~(1 << vss.mStreamType);
}
}
+ updateUserMutableStreams();
}
private void createStreamStates() {
@@ -2414,6 +2422,8 @@
}
pw.print("\n- mute affected streams = 0x");
pw.println(Integer.toHexString(mMuteAffectedStreams));
+ pw.print("\n- user mutable streams = 0x");
+ pw.println(Integer.toHexString(mUserMutableStreams));
}
private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
@@ -2908,6 +2918,7 @@
mMuteAffectedStreams = mSettings.getSystemIntForUser(cr,
System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
UserHandle.USER_CURRENT);
+ updateUserMutableStreams();
updateMasterMono(cr);
@@ -2927,6 +2938,12 @@
mVolumeController.loadSettings(cr);
}
+ private void updateUserMutableStreams() {
+ mUserMutableStreams = mMuteAffectedStreams;
+ mUserMutableStreams &= ~(1 << AudioSystem.STREAM_VOICE_CALL);
+ mUserMutableStreams &= ~(1 << AudioSystem.STREAM_BLUETOOTH_SCO);
+ }
+
@GuardedBy("mSettingsLock")
private void resetActiveAssistantUidsLocked() {
mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
@@ -3800,17 +3817,16 @@
mStreamStates[streamType].getMaxIndex(), streamType);
}
- // Check if volume update should be send to Hearing Aid
- if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
- // only modify the hearing aid attenuation when the stream to modify matches
- // the one expected by the hearing aid
- if (streamType == getBluetoothContextualVolumeStream()) {
- if (DEBUG_VOL) {
- Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
- + newIndex + " stream=" + streamType);
- }
- mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+ // Check if volume update should be send to Hearing Aid.
+ // Only modify the hearing aid attenuation when the stream to modify matches
+ // the one expected by the hearing aid.
+ if (device == AudioSystem.DEVICE_OUT_HEARING_AID
+ && streamType == getBluetoothContextualVolumeStream()) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
+ + newIndex + " stream=" + streamType);
}
+ mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
}
}
@@ -4466,7 +4482,7 @@
}
}
if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
- updateHearingAidVolumeOnVoiceActivityUpdate();
+ postUpdateContextualVolumes();
}
if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) {
mSoundDoseHelper.scheduleMusicActiveCheck();
@@ -4604,89 +4620,55 @@
}
}
- private void updateHearingAidVolumeOnVoiceActivityUpdate() {
- final int streamType = getBluetoothContextualVolumeStream();
- final int index = getStreamVolume(streamType);
- sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
- mVoicePlaybackActive.get(), streamType, index));
- mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+ // delay between audio playback configuration update and checking
+ // actual stream activity to take async playback stop into account
+ private static final int UPDATE_CONTEXTUAL_VOLUME_DELAY_MS = 500;
+
+ /*package*/ void postUpdateContextualVolumes() {
+ sendMsg(mAudioHandler, MSG_UPDATE_CONTEXTUAL_VOLUMES, SENDMSG_REPLACE,
+ /*arg1*/ 0, /*arg2*/ 0, TAG, UPDATE_CONTEXTUAL_VOLUME_DELAY_MS);
}
- /**
- * Manage an audio mode change for audio devices that use an "absolute volume" model,
- * i.e. the framework sends the full scale signal, and the actual volume for the use case
- * is communicated separately.
- */
- void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
- if (oldMode == newMode) {
- return;
- }
- switch (newMode) {
- case AudioSystem.MODE_IN_COMMUNICATION:
- case AudioSystem.MODE_IN_CALL:
- case AudioSystem.MODE_NORMAL:
- case AudioSystem.MODE_CALL_SCREENING:
- case AudioSystem.MODE_CALL_REDIRECT:
- case AudioSystem.MODE_COMMUNICATION_REDIRECT:
- break;
- default:
- // no-op is enough for all other values
- return;
- }
-
- int streamType = getBluetoothContextualVolumeStream(newMode);
+ private void onUpdateContextualVolumes() {
+ final int streamType = getBluetoothContextualVolumeStream();
final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
- final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
- mAbsVolumeMultiModeCaseDevices, deviceTypes);
+ final Set<Integer> absVolumeMultiModeCaseDevices =
+ AudioSystem.intersectionAudioDeviceTypes(
+ mAbsVolumeMultiModeCaseDevices, deviceTypes);
if (absVolumeMultiModeCaseDevices.isEmpty()) {
return;
}
-
- // handling of specific interfaces goes here:
- if (AudioSystem.isSingleAudioDeviceType(
- absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
- final int index = getStreamVolume(streamType);
- sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
- newMode, streamType, index));
- mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
- }
- }
-
- private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index,
- int maxIndex) {
- switch (mode) {
- case AudioSystem.MODE_IN_COMMUNICATION:
- case AudioSystem.MODE_IN_CALL:
- case AudioSystem.MODE_NORMAL:
- case AudioSystem.MODE_CALL_SCREENING:
- case AudioSystem.MODE_CALL_REDIRECT:
- case AudioSystem.MODE_COMMUNICATION_REDIRECT:
- case AudioSystem.MODE_RINGTONE:
- break;
- default:
- // no-op is enough for all other values
- return;
- }
-
- // In some cases (like the outgoing or rejected call) the value of 'device' is not
- // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case
- // may cuase the other devices volume level leaking into the LeAudio device settings.
- if (!AudioSystem.isLeAudioDeviceType(device)) {
- Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device="
- + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
- + " streamType=" + streamType);
+ if (absVolumeMultiModeCaseDevices.size() > 1) {
+ Log.w(TAG, "onUpdateContextualVolumes too many active devices: "
+ + absVolumeMultiModeCaseDevices.stream().map(AudioSystem::getOutputDeviceName)
+ .collect(Collectors.joining(","))
+ + ", for stream: " + streamType);
return;
}
+ final int device = absVolumeMultiModeCaseDevices.toArray(new Integer[0])[0].intValue();
+
+ final int index = getStreamVolume(streamType, device);
+
if (DEBUG_VOL) {
- Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device="
- + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
- + " streamType=" + streamType);
+ Log.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
+ + ", device: " + AudioSystem.getOutputDeviceName(device)
+ + ", index: " + index);
}
- mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
- mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
+
+ if (AudioSystem.isLeAudioDeviceType(device)) {
+ mDeviceBroker.postSetLeAudioVolumeIndex(index * 10,
+ mStreamStates[streamType].getMaxIndex(), streamType);
+ } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
+ mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+ } else {
+ return;
+ }
+
+ sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME,
+ mVoicePlaybackActive.get(), streamType, index, device));
}
private void setStreamVolume(int streamType, int index, int flags,
@@ -6223,9 +6205,7 @@
updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
// change of mode may require volume to be re-applied on some devices
- updateAbsVolumeMultiModeDevices(previousMode, mode);
-
- setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
+ onUpdateContextualVolumes();
synchronized (mCachedAbsVolDrivingStreamsLock) {
mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
@@ -7125,6 +7105,11 @@
return (mMuteAffectedStreams & (1 << streamType)) != 0;
}
+ @Override
+ public boolean isStreamMutableByUi(int streamType) {
+ return (mUserMutableStreams & (1 << streamType)) != 0;
+ }
+
private void ensureValidDirection(int direction) {
switch (direction) {
case AudioManager.ADJUST_LOWER:
@@ -9639,6 +9624,9 @@
case MSG_INIT_SPATIALIZER:
onInitSpatializer();
+ // the device inventory can only be synchronized after the
+ // spatializer has been initialized
+ mDeviceBroker.postSynchronizeAdiDevicesInInventory(null);
mAudioEventWakeLock.release();
break;
@@ -9809,6 +9797,10 @@
onConfigurationChanged();
break;
+ case MSG_UPDATE_CONTEXTUAL_VOLUMES:
+ onUpdateContextualVolumes();
+ break;
+
case MusicFxHelper.MSG_EFFECT_CLIENT_GONE:
mMusicFxHelper.handleMessage(msg);
break;
@@ -11394,7 +11386,8 @@
deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
- mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
+ mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(
+ deviceState, true /*syncInventory*/);
mDeviceBroker.postPersistAudioDeviceSettings();
mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(),
@@ -11963,8 +11956,9 @@
var umi = LocalServices.getService(UserManagerInternal.class);
var pmsi = LocalServices.getService(PermissionManagerServiceInternal.class);
var provider = new AudioServerPermissionProvider(packageStates,
- (Integer uid, String perm) -> (pmsi.checkUidPermission(uid, perm,
- Context.DEVICE_ID_DEFAULT) == PackageManager.PERMISSION_GRANTED),
+ (Integer uid, String perm) -> ActivityManager.checkComponentPermission(perm, uid,
+ /* owningUid = */ -1, /* exported */true)
+ == PackageManager.PERMISSION_GRANTED,
() -> umi.getUserIds()
);
audioPolicy.registerOnStartTask(() -> {
@@ -12326,13 +12320,19 @@
}
@Override
- public void addAssistantServiceUid(int uid) {
+ public void addAssistantServiceUid(int uid, int owningUid) {
+ if (audioserverPermissions()) {
+ mPermissionProvider.setIsolatedServiceUid(uid, owningUid);
+ }
sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
uid, 0, null, 0);
}
@Override
public void removeAssistantServiceUid(int uid) {
+ if (audioserverPermissions()) {
+ mPermissionProvider.clearIsolatedServiceUid(uid);
+ }
sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
uid, 0, null, 0);
}
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 8ea28be..631d5d8 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -227,7 +227,7 @@
static final int VOL_SET_HEARING_AID_VOL = 3;
static final int VOL_SET_AVRCP_VOL = 4;
static final int VOL_ADJUST_VOL_UID = 5;
- static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
+ static final int VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME = 6;
static final int VOL_MODE_CHANGE_HEARING_AID = 7;
static final int VOL_SET_GROUP_VOL = 8;
static final int VOL_MUTE_STREAM_INT = 9;
@@ -299,14 +299,14 @@
logMetricEvent();
}
- /** used for VOL_VOICE_ACTIVITY_HEARING_AID */
- VolumeEvent(int op, boolean voiceActive, int stream, int index) {
+ /** used for VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME */
+ VolumeEvent(int op, boolean voiceActive, int stream, int index, int device) {
mOp = op;
mStream = stream;
mVal1 = index;
mVal2 = voiceActive ? 1 : 0;
// unused
- mVal3 = -1;
+ mVal3 = device;
mCaller = null;
mGroupName = null;
logMetricEvent();
@@ -445,14 +445,16 @@
.set(MediaMetrics.Property.INDEX, mVal1)
.record();
return;
- case VOL_VOICE_ACTIVITY_HEARING_AID:
+ case VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME:
new MediaMetrics.Item(mMetricsId)
- .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid")
+ .set(MediaMetrics.Property.EVENT, "voiceActivityContextualVolume")
.set(MediaMetrics.Property.INDEX, mVal1)
.set(MediaMetrics.Property.STATE,
mVal2 == 1 ? "active" : "inactive")
.set(MediaMetrics.Property.STREAM_TYPE,
AudioSystem.streamToString(mStream))
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getOutputDeviceName(mVal3))
.record();
return;
case VOL_MODE_CHANGE_HEARING_AID:
@@ -538,11 +540,12 @@
.append(" flags:0x").append(Integer.toHexString(mVal2))
.append(") from ").append(mCaller)
.toString();
- case VOL_VOICE_ACTIVITY_HEARING_AID:
+ case VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME:
return new StringBuilder("Voice activity change (")
.append(mVal2 == 1 ? "active" : "inactive")
- .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+ .append(") causes setting volume to idx:").append(mVal1)
.append(" stream:").append(AudioSystem.streamToString(mStream))
+ .append(" device:").append(AudioSystem.getOutputDeviceName(mVal3))
.toString();
case VOL_MODE_CHANGE_HEARING_AID:
return new StringBuilder("setMode(")
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 8008717..0de3428 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -142,7 +142,6 @@
private static final int SCO_MODE_MAX = 2;
private static final int BT_HEARING_AID_GAIN_MIN = -128;
- private static final int BT_LE_AUDIO_MIN_VOL = 0;
private static final int BT_LE_AUDIO_MAX_VOL = 255;
// BtDevice constants currently rolling out under flag protection. Use own
@@ -211,8 +210,7 @@
//----------------------------------------------------------------------
// Interface for AudioDeviceBroker
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package*/ synchronized void onSystemReady() {
mScoConnectionState = android.media.AudioManager.SCO_AUDIO_STATE_ERROR;
resetBluetoothSco();
@@ -373,8 +371,7 @@
return codecAndChanged;
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package*/ synchronized void onReceiveBtEvent(Intent intent) {
final String action = intent.getAction();
@@ -396,78 +393,67 @@
}
/**
- * Exclusively called from AudioDeviceBroker when handling MSG_L_RECEIVED_BT_EVENT
+ * Exclusively called from AudioDeviceBroker (with mSetModeLock held)
+ * when handling MSG_L_RECEIVED_BT_EVENT in {@link #onReceiveBtEvent(Intent)}
* as part of the serialization of the communication route selection
*/
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ @GuardedBy("BtHelper.this")
private void onScoAudioStateChanged(int state) {
boolean broadcast = false;
int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
- Log.i(TAG, "onScoAudioStateChanged state: " + state + " mScoAudioState: " + mScoAudioState);
- if (mDeviceBroker.isScoManagedByAudio()) {
- switch (state) {
- case BluetoothHeadset.STATE_AUDIO_CONNECTED:
- mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged");
- scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
+ Log.i(TAG, "onScoAudioStateChanged state: " + state
+ + ", mScoAudioState: " + mScoAudioState);
+ switch (state) {
+ case BluetoothHeadset.STATE_AUDIO_CONNECTED:
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+ && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ } else if (mDeviceBroker.isBluetoothScoRequested()) {
+ // broadcast intent if the connection was initated by AudioService
broadcast = true;
- break;
- case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
- mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged");
- scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
- broadcast = true;
- break;
- default:
- break;
- }
- } else {
- switch (state) {
- case BluetoothHeadset.STATE_AUDIO_CONNECTED:
- scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
- if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
- && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
- } else if (mDeviceBroker.isBluetoothScoRequested()) {
- // broadcast intent if the connection was initated by AudioService
- broadcast = true;
- }
+ }
+ if (!mDeviceBroker.isScoManagedByAudio()) {
mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged");
- break;
- case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+ }
+ break;
+ case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+ if (!mDeviceBroker.isScoManagedByAudio()) {
mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged");
- scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
- // There are two cases where we want to immediately reconnect audio:
- // 1) If a new start request was received while disconnecting: this was
- // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ.
- // 2) If audio was connected then disconnected via Bluetooth APIs and
- // we still have pending activation requests by apps: this is indicated by
- // state SCO_STATE_ACTIVE_EXTERNAL and BT SCO is requested.
- if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
- if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
- && connectBluetoothScoAudioHelper(mBluetoothHeadset,
- mBluetoothHeadsetDevice, mScoAudioMode)) {
- mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
- broadcast = true;
- break;
- }
- }
- if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
+ }
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
+ // There are two cases where we want to immediately reconnect audio:
+ // 1) If a new start request was received while disconnecting: this was
+ // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ.
+ // 2) If audio was connected then disconnected via Bluetooth APIs and
+ // we still have pending activation requests by apps: this is indicated by
+ // state SCO_STATE_ACTIVE_EXTERNAL and BT SCO is requested.
+ if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
+ if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
+ && connectBluetoothScoAudioHelper(mBluetoothHeadset,
+ mBluetoothHeadsetDevice, mScoAudioMode)) {
+ mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
broadcast = true;
+ break;
}
- mScoAudioState = SCO_STATE_INACTIVE;
- break;
- case BluetoothHeadset.STATE_AUDIO_CONNECTING:
- if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
- && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
- }
- break;
- default:
- break;
- }
+ }
+ if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
+ broadcast = true;
+ }
+ mScoAudioState = SCO_STATE_INACTIVE;
+ break;
+ case BluetoothHeadset.STATE_AUDIO_CONNECTING:
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+ && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ }
+ break;
+ default:
+ break;
}
if (broadcast) {
+ Log.i(TAG, "onScoAudioStateChanged broadcasting state: " + scoAudioState);
broadcastScoConnectionState(scoAudioState);
//FIXME: this is to maintain compatibility with deprecated intent
// AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
@@ -493,16 +479,14 @@
|| mScoAudioState == SCO_STATE_ACTIVATE_REQ;
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package*/ synchronized boolean startBluetoothSco(int scoAudioMode,
@NonNull String eventSource) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource));
return requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package*/ synchronized boolean stopBluetoothSco(@NonNull String eventSource) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource));
return requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, SCO_MODE_VIRTUAL_CALL);
@@ -574,8 +558,7 @@
mScoConnectionState = state;
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package*/ synchronized void resetBluetoothSco() {
mScoAudioState = SCO_STATE_INACTIVE;
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
@@ -584,8 +567,7 @@
mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package*/ synchronized void onBtProfileDisconnected(int profile) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
"BT profile " + BluetoothProfile.getProfileName(profile)
@@ -649,8 +631,7 @@
MyLeAudioCallback mLeAudioCallback = null;
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package*/ synchronized void onBtProfileConnected(int profile, BluetoothProfile proxy) {
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
"BT profile " + BluetoothProfile.getProfileName(profile) + " connected to proxy "
@@ -787,8 +768,7 @@
}
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
private void onHeadsetProfileConnected(@NonNull BluetoothHeadset headset) {
// Discard timeout message
mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService();
@@ -931,8 +911,7 @@
return btDevice == null ? "(null)" : btDevice.getAnonymizedAddress();
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+ // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
/*package */ synchronized void onSetBtScoActiveDevice(BluetoothDevice btDevice) {
Log.i(TAG, "onSetBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice)
+ " -> " + getAnonymizedAddress(btDevice));
@@ -1133,6 +1112,9 @@
//-----------------------------------------------------
// Utilities
+
+ // suppress warning due to generic Intent passed as param
+ @SuppressWarnings("AndroidFrameworkRequiresPermission")
private void sendStickyBroadcastToAll(Intent intent) {
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index 5c74304..ded93e6 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -643,9 +643,9 @@
if (index > safeIndex) {
streamState.setIndex(safeIndex, deviceType, caller,
true /*hasModifyAudioSettings*/);
- mAudioHandler.sendMessageAtTime(
+ mAudioHandler.sendMessage(
mAudioHandler.obtainMessage(MSG_SET_DEVICE_VOLUME, deviceType,
- /*arg2=*/0, streamState), /*delay=*/0);
+ /*arg2=*/0, streamState));
}
}
}
@@ -686,8 +686,11 @@
/*package*/ void disableSafeMediaVolume(String callingPackage) {
synchronized (mSafeMediaVolumeStateLock) {
final long identity = Binder.clearCallingIdentity();
- setSafeMediaVolumeEnabled(false, callingPackage);
- Binder.restoreCallingIdentity(identity);
+ try {
+ setSafeMediaVolumeEnabled(false, callingPackage);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
if (mPendingVolumeCommand != null) {
mAudioService.onSetStreamVolume(mPendingVolumeCommand.mStreamType,
@@ -701,6 +704,7 @@
}
}
+ @SuppressWarnings("AndroidFrameworkRequiresPermission")
/*package*/ void scheduleMusicActiveCheck() {
synchronized (mSafeMediaVolumeStateLock) {
cancelMusicActiveCheck();
@@ -1035,10 +1039,9 @@
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
}
- mAudioHandler.sendMessageAtTime(
+ mAudioHandler.sendMessage(
mAudioHandler.obtainMessage(MSG_PERSIST_SAFE_VOLUME_STATE,
- persistedState, /*arg2=*/0,
- /*obj=*/null), /*delay=*/0);
+ persistedState, /*arg2=*/0, /*obj=*/null));
}
private void updateCsdEnabled(String caller) {
@@ -1199,8 +1202,8 @@
sanitizeDoseRecords_l();
- mAudioHandler.sendMessageAtTime(mAudioHandler.obtainMessage(MSG_PERSIST_CSD_VALUES,
- /* arg1= */0, /* arg2= */0, /* obj= */null), /* delay= */0);
+ mAudioHandler.sendMessage(mAudioHandler.obtainMessage(MSG_PERSIST_CSD_VALUES,
+ /* arg1= */0, /* arg2= */0, /* obj= */null));
mLogger.enqueue(SoundDoseEvent.getDoseUpdateEvent(currentCsd, totalDuration));
}
@@ -1316,6 +1319,7 @@
}
/** Called when handling MSG_LOWER_VOLUME_TO_RS1 */
+ @SuppressWarnings("AndroidFrameworkRequiresPermission")
private void onLowerVolumeToRs1() {
final ArrayList<AudioDeviceAttributes> devices = mAudioService.getDevicesForAttributesInt(
new AudioAttributes.Builder().setUsage(
@@ -1360,9 +1364,9 @@
@Override
public String toString() {
- return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=")
- .append(mIndex).append(",flags=").append(mFlags).append(",device=")
- .append(mDevice).append('}').toString();
+ return "{streamType=" + mStreamType
+ + ",index=" + mIndex + ",flags=" + mFlags
+ + ",device=" + mDevice + "}";
}
}
}
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index cae1695..9265ff2 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -568,7 +568,8 @@
updatedDevice = new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
ada.getAddress());
initSAState(updatedDevice);
- mDeviceBroker.addOrUpdateDeviceSAStateInInventory(updatedDevice);
+ mDeviceBroker.addOrUpdateDeviceSAStateInInventory(
+ updatedDevice, true /*syncInventory*/);
}
if (updatedDevice != null) {
onRoutingUpdated();
@@ -723,7 +724,7 @@
new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
ada.getAddress());
initSAState(deviceState);
- mDeviceBroker.addOrUpdateDeviceSAStateInInventory(deviceState);
+ mDeviceBroker.addOrUpdateDeviceSAStateInInventory(deviceState, true /*syncInventory*/);
mDeviceBroker.postPersistAudioDeviceSettings();
logDeviceState(deviceState, "addWirelessDeviceIfNew"); // may be updated later.
}
diff --git a/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java b/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
index 1726da2..a83813f 100644
--- a/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
+++ b/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
@@ -18,6 +18,8 @@
import android.annotation.NonNull;
import android.annotation.UserIdInt;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType;
import android.app.backup.BlobBackupHelper;
import android.util.Slog;
@@ -33,6 +35,16 @@
private static final String TAG = "AppLocalesBackupHelper"; // must be < 23 chars
private static final boolean DEBUG = false;
+ @BackupRestoreDataType
+ private static final String DATA_TYPE_APP_LOCALES = "app_locales:locales";
+
+ @BackupRestoreError
+ private static final String ERROR_UNEXPECTED_KEY = "unexpected_key";
+ @BackupRestoreError
+ private static final String ERROR_BACKUP_FAILED = "backup_failed";
+ @BackupRestoreError
+ private static final String ERROR_RESTORE_FAILED = "restore_failed";
+
// Current version of the blob schema
private static final int BLOB_VERSION = 1;
@@ -59,13 +71,24 @@
if (KEY_APP_LOCALES.equals(key)) {
try {
newPayload = mLocaleManagerInternal.getBackupPayload(mUserId);
+ getLogger().logItemsBackedUp(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1);
} catch (Exception e) {
// Treat as no data
Slog.e(TAG, "Couldn't communicate with locale manager", e);
+ getLogger().logItemsBackupFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_BACKUP_FAILED);
newPayload = null;
}
} else {
Slog.w(TAG, "Unexpected backup key " + key);
+ getLogger().logItemsBackupFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_UNEXPECTED_KEY);
}
return newPayload;
}
@@ -79,11 +102,22 @@
if (KEY_APP_LOCALES.equals(key)) {
try {
mLocaleManagerInternal.stageAndApplyRestoredPayload(payload, mUserId);
+ getLogger().logItemsRestored(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1);
} catch (Exception e) {
Slog.e(TAG, "Couldn't communicate with locale manager", e);
+ getLogger().logItemsRestoreFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_RESTORE_FAILED);
}
} else {
Slog.w(TAG, "Unexpected restore key " + key);
+ getLogger().logItemsBackupFailed(
+ DATA_TYPE_APP_LOCALES,
+ /* count= */ 1,
+ ERROR_UNEXPECTED_KEY);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java
index 6a2731d..5a493e4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceRegistry.java
@@ -120,11 +120,13 @@
// Register each sensor individually with BiometricService
final List<P> allProps = new ArrayList<>();
for (T provider : providers) {
- final List<P> props = provider.getSensorProperties();
- for (P prop : props) {
- registerService(biometricService, prop);
+ if(provider != null) {
+ final List<P> props = provider.getSensorProperties();
+ for (P prop : props) {
+ registerService(biometricService, prop);
+ }
+ allProps.addAll(props);
}
- allProps.addAll(props);
}
finishRegistration(providers, allProps);
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index b179783..6e38733 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -20,6 +20,8 @@
import android.annotation.Nullable;
import android.companion.virtual.IVirtualDevice;
import android.companion.virtual.VirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
+import android.companion.virtual.VirtualDeviceParams;
import android.companion.virtual.sensor.VirtualSensor;
import android.content.Context;
import android.os.LocaleList;
@@ -180,4 +182,14 @@
* exists, as long as one may have existed or can be created.
*/
public abstract @NonNull Set<String> getAllPersistentDeviceIds();
+
+ /**
+ * Creates a virtual device where applications can launch and receive input events injected by
+ * the creator.
+ *
+ * <p>A Companion Device Manager association is not required. Only the system may create such
+ * virtual devices.</p>
+ */
+ public abstract @NonNull VirtualDeviceManager.VirtualDevice createVirtualDevice(
+ @NonNull VirtualDeviceParams params);
}
diff --git a/services/core/java/com/android/server/crashrecovery/TEST_MAPPING b/services/core/java/com/android/server/crashrecovery/TEST_MAPPING
new file mode 100644
index 0000000..4a66bac
--- /dev/null
+++ b/services/core/java/com/android/server/crashrecovery/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "postsubmit": [
+ {
+ "name": "FrameworksMockingServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.RescuePartyTest"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index e8394d4..619aecf 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -19,6 +19,9 @@
import static android.Manifest.permission.CONTROL_DEVICE_STATE;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
@@ -47,6 +50,8 @@
import android.hardware.devicestate.DeviceStateManagerInternal;
import android.hardware.devicestate.IDeviceStateManager;
import android.hardware.devicestate.IDeviceStateManagerCallback;
+import android.hardware.devicestate.feature.flags.FeatureFlags;
+import android.hardware.devicestate.feature.flags.FeatureFlagsImpl;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -175,7 +180,7 @@
private Set<Integer> mDeviceStatesAvailableForAppRequests = new HashSet<>();
- private Set<Integer> mFoldedDeviceStates;
+ private Set<Integer> mFoldedDeviceStates = new HashSet<>();
@Nullable
private DeviceState mRearDisplayState;
@@ -185,6 +190,9 @@
@Nullable
private OverrideRequest mRearDisplayPendingOverrideRequest;
+ @NonNull
+ private final FeatureFlags mFlags;
+
@VisibleForTesting
interface SystemPropertySetter {
void setDebugTracingDeviceStateProperty(String value);
@@ -245,6 +253,7 @@
@NonNull SystemPropertySetter systemPropertySetter) {
super(context);
mSystemPropertySetter = systemPropertySetter;
+ mFlags = new FeatureFlagsImpl();
// We use the DisplayThread because this service indirectly drives
// display (on/off) and window (position) events through its callbacks.
DisplayThread displayThread = DisplayThread.get();
@@ -270,9 +279,12 @@
publishBinderService(Context.DEVICE_STATE_SERVICE, mBinderService);
publishLocalService(DeviceStateManagerInternal.class, new LocalService());
- synchronized (mLock) {
- readStatesAvailableForRequestFromApps();
- mFoldedDeviceStates = readFoldedStates();
+ if (!mFlags.deviceStatePropertyMigration()) {
+ synchronized (mLock) {
+ readStatesAvailableForRequestFromApps();
+ mFoldedDeviceStates = readFoldedStates();
+ setRearDisplayStateLocked();
+ }
}
mActivityTaskManagerInternal.registerScreenObserver(mOverrideRequestScreenObserver);
@@ -461,8 +473,6 @@
mOverrideRequestController.handleNewSupportedStates(newStateIdentifiers, reason);
updatePendingStateLocked();
- setRearDisplayStateLocked();
-
notifyDeviceStateInfoChangedAsync();
mHandler.post(this::notifyPolicyIfNeeded);
@@ -838,12 +848,22 @@
OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
deviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);
- // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
- if (!hasControlDeviceStatePermission && mRearDisplayState != null
- && state == mRearDisplayState.getIdentifier()) {
- showRearDisplayEducationalOverlayLocked(request);
+ if (mFlags.deviceStatePropertyMigration()) {
+ // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
+ if (!hasControlDeviceStatePermission && deviceState.get().hasProperty(
+ PROPERTY_FEATURE_REAR_DISPLAY)) {
+ showRearDisplayEducationalOverlayLocked(request);
+ } else {
+ mOverrideRequestController.addRequest(request);
+ }
} else {
- mOverrideRequestController.addRequest(request);
+ // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
+ if (!hasControlDeviceStatePermission && mRearDisplayState != null
+ && state == mRearDisplayState.getIdentifier()) {
+ showRearDisplayEducationalOverlayLocked(request);
+ } else {
+ mOverrideRequestController.addRequest(request);
+ }
}
}
}
@@ -1034,7 +1054,13 @@
private boolean isStateAvailableForAppRequests(int state) {
synchronized (mLock) {
- return mDeviceStatesAvailableForAppRequests.contains(state);
+ if (mFlags.deviceStatePropertyMigration()) {
+ Optional<DeviceState> deviceState = getStateLocked(state);
+ return deviceState.isPresent() && deviceState.get().hasProperty(
+ PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST);
+ } else {
+ return mDeviceStatesAvailableForAppRequests.contains(state);
+ }
}
}
@@ -1096,9 +1122,20 @@
*/
@GuardedBy("mLock")
private boolean isDeviceOpeningLocked(int newBaseState) {
- return mBaseState.filter(
- deviceState -> mFoldedDeviceStates.contains(deviceState.getIdentifier())
- && !mFoldedDeviceStates.contains(newBaseState)).isPresent();
+ if (mFlags.deviceStatePropertyMigration()) {
+ final DeviceState currentBaseState = mBaseState.orElse(INVALID_DEVICE_STATE);
+ final DeviceState newDeviceBaseState = getStateLocked(newBaseState).orElse(
+ INVALID_DEVICE_STATE);
+
+ return currentBaseState.hasProperty(
+ PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)
+ && !newDeviceBaseState.hasProperty(
+ PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY);
+ } else {
+ return mBaseState.filter(
+ deviceState -> mFoldedDeviceStates.contains(deviceState.getIdentifier())
+ && !mFoldedDeviceStates.contains(newBaseState)).isPresent();
+ }
}
private final class DeviceStateProviderListener implements DeviceStateProvider.Listener {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index e686779..5f1bc2a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -598,10 +598,11 @@
FoldSettingProvider foldSettingProvider = new FoldSettingProvider(context,
new SettingsWrapper(),
new FoldLockSettingAvailabilityProvider(context.getResources()));
+ Looper displayThreadLooper = DisplayThread.get().getLooper();
mInjector = injector;
mContext = context;
mFlags = injector.getFlags();
- mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
+ mHandler = new DisplayManagerHandler(displayThreadLooper);
mUiHandler = UiThread.getHandler();
mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
@@ -609,7 +610,7 @@
mDisplayDeviceRepo, new LogicalDisplayListener(), mSyncRoot, mHandler, mFlags);
mDisplayModeDirector = new DisplayModeDirector(
context, mHandler, mFlags, mDisplayDeviceConfigProvider);
- mBrightnessSynchronizer = new BrightnessSynchronizer(mContext,
+ mBrightnessSynchronizer = new BrightnessSynchronizer(mContext, displayThreadLooper,
mFlags.isBrightnessIntRangeUserPerceptionEnabled());
Resources resources = mContext.getResources();
mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
@@ -822,6 +823,13 @@
}
@VisibleForTesting
+ void setDisplayState(int displayId, int state) {
+ synchronized (mSyncRoot) {
+ mDisplayStates.setValueAt(displayId, state);
+ }
+ }
+
+ @VisibleForTesting
Handler getDisplayHandler() {
return mHandler;
}
@@ -3410,27 +3418,39 @@
}
}
- boolean requestDisplayPower(int displayId, boolean on) {
+ boolean requestDisplayPower(int displayId, int requestedState) {
synchronized (mSyncRoot) {
final var display = mLogicalDisplayMapper.getDisplayLocked(displayId);
if (display == null) {
- Slog.w(TAG, "requestDisplayPower: Cannot find a display with displayId="
+ Slog.w(TAG, "requestDisplayPower: Cannot find the display with displayId="
+ displayId);
return false;
}
+ var state = requestedState;
+ if (state == Display.STATE_UNKNOWN) {
+ state = mDisplayStates.get(displayId);
+ }
+
final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
+ var brightnessState = brightnessPair.brightness;
+ if (state == Display.STATE_OFF) {
+ brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
+ }
+
var runnable = display.getPrimaryDisplayDeviceLocked().requestDisplayStateLocked(
- on ? Display.STATE_ON : Display.STATE_OFF,
- on ? brightnessPair.brightness : PowerManager.BRIGHTNESS_OFF_FLOAT,
+ state,
+ brightnessState,
brightnessPair.sdrBrightness,
display.getDisplayOffloadSessionLocked());
if (runnable == null) {
- Slog.w(TAG, "requestDisplayPower: Cannot update the power state to ON=" + on
- + " for a display with displayId=" + displayId + ", runnable is null");
+ Slog.w(TAG, "requestDisplayPower: Cannot set power state = " + state
+ + " for the display with displayId=" + displayId + ","
+ + " requestedState=" + requestedState + ": runnable is null");
return false;
}
runnable.run();
- Slog.i(TAG, "requestDisplayPower(displayId=" + displayId + ", on=" + on + ")");
+ Slog.i(TAG, "requestDisplayPower(displayId=" + displayId
+ + ", requestedState=" + requestedState + "): state set to " + state);
}
return true;
}
@@ -4659,9 +4679,9 @@
}
@EnforcePermission(MANAGE_DISPLAYS)
- public boolean requestDisplayPower(int displayId, boolean on) {
+ public boolean requestDisplayPower(int displayId, int state) {
requestDisplayPower_enforcePermission();
- return DisplayManagerService.this.requestDisplayPower(displayId, on);
+ return DisplayManagerService.this.requestDisplayPower(displayId, state);
}
@EnforcePermission(RESTRICT_DISPLAY_MODES)
diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
index d973b71..9eef657 100644
--- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
+++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
@@ -106,10 +106,10 @@
return setDisplayEnabled(true);
case "disable-display":
return setDisplayEnabled(false);
- case "power-on":
- return requestDisplayPower(true);
+ case "power-reset":
+ return requestDisplayPower(Display.STATE_UNKNOWN);
case "power-off":
- return requestDisplayPower(false);
+ return requestDisplayPower(Display.STATE_OFF);
default:
return handleDefaultCommands(cmd);
}
@@ -183,6 +183,10 @@
pw.println(" disable-display DISPLAY_ID");
pw.println(" Disable the DISPLAY_ID. Only possible if this is a connected display.");
}
+ pw.println(" power-reset DISPLAY_ID");
+ pw.println(" Turn the DISPLAY_ID power to a state the display supposed to have.");
+ pw.println(" power-off DISPLAY_ID");
+ pw.println(" Turn the display DISPLAY_ID power off.");
pw.println();
Intent.printIntentArgsHelp(pw , "");
}
@@ -597,7 +601,7 @@
return 0;
}
- private int requestDisplayPower(boolean enable) {
+ private int requestDisplayPower(int state) {
final String displayIdText = getNextArg();
if (displayIdText == null) {
getErrPrintWriter().println("Error: no displayId specified");
@@ -610,7 +614,7 @@
getErrPrintWriter().println("Error: invalid displayId: '" + displayIdText + "'");
return 1;
}
- mService.requestDisplayPower(displayId, enable);
+ mService.requestDisplayPower(displayId, state);
return 0;
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index de9715a..7cd9144 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -2098,7 +2098,7 @@
private void onDisplayOffloadUnblockScreenOn(DisplayOffloadSession displayOffloadSession) {
Message msg = mHandler.obtainMessage(MSG_OFFLOADING_SCREEN_ON_UNBLOCKED,
displayOffloadSession);
- mHandler.sendMessage(msg);
+ mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
}
private void unblockScreenOnByDisplayOffload() {
@@ -2116,7 +2116,7 @@
if (mDisplayOffloadSession == null) {
return;
}
- if (mPendingScreenOnUnblockerByDisplayOffload != null) {
+ if (mPendingScreenOnUnblockerByDisplayOffload == null) {
// Already unblocked.
return;
}
@@ -2134,7 +2134,6 @@
// If the screen is turning on, give displayoffload a chance to do something before the
// screen actually turns on.
- // TODO(b/316941732): add tests for this displayoffload screen-on blocker.
if (isOn && changed && !mScreenTurningOnWasBlockedByDisplayOffload) {
blockScreenOnByDisplayOffload(mDisplayOffloadSession);
} else if (!isOn && mScreenTurningOnWasBlockedByDisplayOffload) {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 44846f3..6e0b9cf 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -49,6 +49,7 @@
import android.view.SurfaceControl;
import com.android.internal.R;
+import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -1442,8 +1443,9 @@
}
public static class Injector {
- // Native callback.
+ // Ensure the callback is kept to preserve native weak reference lifecycle semantics.
@SuppressWarnings("unused")
+ @KeepForWeakReference
private ProxyDisplayEventReceiver mReceiver;
public void setDisplayEventListenerLocked(Looper looper, DisplayEventListener listener) {
mReceiver = new ProxyDisplayEventReceiver(looper, listener);
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 18a9986..886857c 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -1079,6 +1079,21 @@
}
@Override // Binder call
+ public void finishSelfOneway(IBinder token, boolean immediate) {
+ // Requires no permission, called by Dream from an arbitrary process.
+ if (token == null) {
+ throw new IllegalArgumentException("token must not be null");
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ finishSelfInternal(token, immediate);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
public void startDozing(
IBinder token, int screenState, @Display.StateReason int reason,
int screenBrightness) {
@@ -1096,6 +1111,23 @@
}
@Override // Binder call
+ public void startDozingOneway(
+ IBinder token, int screenState, @Display.StateReason int reason,
+ int screenBrightness) {
+ // Requires no permission, called by Dream from an arbitrary process.
+ if (token == null) {
+ throw new IllegalArgumentException("token must not be null");
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ startDozingInternal(token, screenState, reason, screenBrightness);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
public void stopDozing(IBinder token) {
// Requires no permission, called by Dream from an arbitrary process.
if (token == null) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index cd2c037..5696fba 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -427,7 +427,7 @@
@ServiceThreadOnly
void setHpdSignalType(@Constants.HpdSignalType int signal, int portId) {
assertRunOnServiceThread();
- HdmiLogger.debug("setHpdSignalType: portId %b, signal %b", portId, signal);
+ HdmiLogger.debug("setHpdSignalType: portId %d, signal %d", portId, signal);
mNativeWrapperImpl.nativeSetHpdSignalType(signal, portId);
}
@@ -439,7 +439,7 @@
@Constants.HpdSignalType
int getHpdSignalType(int portId) {
assertRunOnServiceThread();
- HdmiLogger.debug("getHpdSignalType: portId %b ", portId);
+ HdmiLogger.debug("getHpdSignalType: portId %d ", portId);
return mNativeWrapperImpl.nativeGetHpdSignalType(portId);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 275c930..0f9c344 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -67,7 +67,7 @@
/**
* Represent a logical device of type TV residing in Android system.
*/
-public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
+public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
private static final String TAG = "HdmiCecLocalDeviceTv";
// Whether ARC is available or not. "true" means that ARC is established between TV and
@@ -113,6 +113,18 @@
// handle.
private final DelayedMessageBuffer mDelayedMessageBuffer = new DelayedMessageBuffer(this);
+ private boolean mWasActiveSourceSetToConnectedDevice = false;
+
+ @VisibleForTesting
+ protected boolean getWasActiveSourceSetToConnectedDevice() {
+ return mWasActiveSourceSetToConnectedDevice;
+ }
+
+ protected void setWasActiveSourceSetToConnectedDevice(
+ boolean wasActiveSourceSetToConnectedDevice) {
+ mWasActiveSourceSetToConnectedDevice = wasActiveSourceSetToConnectedDevice;
+ }
+
// Defines the callback invoked when TV input framework is updated with input status.
// We are interested in the notification for HDMI input addition event, in order to
// process any CEC commands that arrived before the input is added.
@@ -474,6 +486,7 @@
|| info.getDeviceType() == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
mService.getHdmiCecNetwork().updateDevicePowerStatus(logicalAddress,
HdmiControlManager.POWER_STATUS_ON);
+ setWasActiveSourceSetToConnectedDevice(true);
ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress);
ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType());
} else {
@@ -489,13 +502,16 @@
protected int handleStandby(HdmiCecMessage message) {
assertRunOnServiceThread();
- // Ignore <Standby> from non-active source device.
- if (getActiveSource().logicalAddress != message.getSource()) {
+ // If a device has previously asserted the active source status, ignore <Standby> from
+ // non-active source.
+ if (getWasActiveSourceSetToConnectedDevice()
+ && getActiveSource().logicalAddress != message.getSource()) {
Slog.d(TAG, "<Standby> was not sent by the current active source, ignoring."
+ " Current active source has logical address "
+ getActiveSource().logicalAddress);
return Constants.HANDLED;
}
+ setWasActiveSourceSetToConnectedDevice(false);
return super.handleStandby(message);
}
@@ -1457,6 +1473,7 @@
invokeStandbyCompletedCallback(callback);
return;
}
+ setWasActiveSourceSetToConnectedDevice(false);
boolean sendStandbyOnSleep =
mService.getHdmiCecConfig().getIntValue(
HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP)
diff --git a/services/core/java/com/android/server/health/HealthServiceWrapper.java b/services/core/java/com/android/server/health/HealthServiceWrapper.java
index 25d1a88..9c14b5b 100644
--- a/services/core/java/com/android/server/health/HealthServiceWrapper.java
+++ b/services/core/java/com/android/server/health/HealthServiceWrapper.java
@@ -71,6 +71,21 @@
public abstract android.hardware.health.HealthInfo getHealthInfo() throws RemoteException;
/**
+ * Calls into getBatteryHealthData() in the health HAL.
+ * This function does not have a corresponding HIDL implementation, so
+ * returns null by default, unless there is an AIDL class that overrides
+ * this one.
+ *
+ * @return battery health data. {@code null} if no health HAL service.
+ * {@code null} if any service-specific error when calling {@code
+ * getBatteryHealthData}, e.g. it is unsupported.
+ * @throws RemoteException for any transaction-level errors
+ */
+ public android.hardware.health.BatteryHealthData getBatteryHealthData() throws RemoteException {
+ return null;
+ }
+
+ /**
* Create a new HealthServiceWrapper instance.
*
* @param healthInfoCallback the callback to call when health info changes
diff --git a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java
index fd3a92e..2a3fbc3 100644
--- a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java
+++ b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java
@@ -212,6 +212,17 @@
}
}
+ @Override
+ public BatteryHealthData getBatteryHealthData() throws RemoteException {
+ IHealth service = mLastService.get();
+ if (service == null) return null;
+ try {
+ return service.getBatteryHealthData();
+ } catch (UnsupportedOperationException | ServiceSpecificException ex) {
+ return null;
+ }
+ }
+
public void setChargingPolicy(int policy) throws RemoteException {
IHealth service = mLastService.get();
if (service == null) return;
diff --git a/services/core/java/com/android/server/input/BatteryController.java b/services/core/java/com/android/server/input/BatteryController.java
index 38a0d37..62c21bd 100644
--- a/services/core/java/com/android/server/input/BatteryController.java
+++ b/services/core/java/com/android/server/input/BatteryController.java
@@ -83,6 +83,7 @@
private final Handler mHandler;
private final UEventManager mUEventManager;
private final BluetoothBatteryManager mBluetoothBatteryManager;
+ private final Runnable mHandlePollEventCallback = this::handlePollEvent;
// Maps a pid to the registered listener record for that process. There can only be one battery
// listener per process.
@@ -206,7 +207,7 @@
if (!mIsInteractive || !anyOf(mDeviceMonitors, DeviceMonitor::requiresPolling)) {
// Stop polling.
mIsPolling = false;
- mHandler.removeCallbacks(this::handlePollEvent);
+ mHandler.removeCallbacks(mHandlePollEventCallback);
return;
}
@@ -215,7 +216,7 @@
}
// Start polling.
mIsPolling = true;
- mHandler.postDelayed(this::handlePollEvent, delayStart ? POLLING_PERIOD_MILLIS : 0);
+ mHandler.postDelayed(mHandlePollEventCallback, delayStart ? POLLING_PERIOD_MILLIS : 0);
}
private <R> R processInputDevice(int deviceId, R defaultValue, Function<InputDevice, R> func) {
@@ -366,7 +367,7 @@
}
final long eventTime = SystemClock.uptimeMillis();
mDeviceMonitors.forEach((deviceId, monitor) -> monitor.onPoll(eventTime));
- mHandler.postDelayed(this::handlePollEvent, POLLING_PERIOD_MILLIS);
+ mHandler.postDelayed(mHandlePollEventCallback, POLLING_PERIOD_MILLIS);
}
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e5dbce9..bef984b 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -53,6 +53,7 @@
import android.hardware.input.InputManager;
import android.hardware.input.InputSensorInfo;
import android.hardware.input.InputSettings;
+import android.hardware.input.KeyGlyphMap;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult;
import android.hardware.input.TouchCalibration;
@@ -311,6 +312,9 @@
// Manages Keyboard modifier keys remapping
private final KeyRemapper mKeyRemapper;
+ // Manages Keyboard glyphs for specific keyboards
+ private final KeyboardGlyphManager mKeyboardGlyphManager;
+
// Manages loading PointerIcons
private final PointerIconCache mPointerIconCache;
@@ -460,6 +464,7 @@
mKeyboardLedController = new KeyboardLedController(mContext, injector.getLooper(),
mNative);
mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper());
+ mKeyboardGlyphManager = new KeyboardGlyphManager(mContext, injector.getLooper());
mPointerIconCache = new PointerIconCache(mContext, mNative);
mUseDevInputEventForAudioJack =
@@ -576,6 +581,7 @@
mKeyboardLedController.systemRunning();
mKeyRemapper.systemRunning();
mPointerIconCache.systemRunning();
+ mKeyboardGlyphManager.systemRunning();
}
private void reloadDeviceAliases() {
@@ -1208,6 +1214,11 @@
imeInfo, imeSubtype);
}
+ @Override // Binder call
+ public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+ return mKeyboardGlyphManager.getKeyGlyphMap(deviceId);
+ }
+
public void setFocusedApplication(int displayId, InputApplicationHandle application) {
mNative.setFocusedApplication(displayId, application);
}
@@ -2077,6 +2088,7 @@
mBatteryController.dump(ipw);
mKeyboardBacklightController.dump(ipw);
mKeyboardLedController.dump(ipw);
+ mKeyboardGlyphManager.dump(ipw);
}
private void dumpAssociations(IndentingPrintWriter pw) {
diff --git a/services/core/java/com/android/server/input/KeyboardGlyphManager.java b/services/core/java/com/android/server/input/KeyboardGlyphManager.java
new file mode 100644
index 0000000..f59d72b
--- /dev/null
+++ b/services/core/java/com/android/server/input/KeyboardGlyphManager.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2024 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.input;
+
+import static com.android.hardware.input.Flags.keyboardGlyphMap;
+
+import android.annotation.AnyRes;
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.hardware.input.InputManager;
+import android.hardware.input.KeyGlyphMap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.InputDevice;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Provides information on custom glyphs configured for specific keyboard devices.
+ *
+ * @hide
+ */
+public final class KeyboardGlyphManager implements InputManager.InputDeviceListener {
+
+ private static final String TAG = "KeyboardGlyphManager";
+ // To enable these logs, run: 'adb shell setprop log.tag.KeyboardGlyphManager DEBUG'
+ // (requires restart)
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private static final String TAG_KEYBOARD_GLYPH_MAPS = "keyboard-glyph-maps";
+ private static final String TAG_KEYBOARD_GLYPH_MAP = "keyboard-glyph-map";
+ private static final String TAG_KEY_GLYPH = "key-glyph";
+ private static final String TAG_MODIFIER_GLYPH = "modifier-glyph";
+ private static final String TAG_FUNCTION_ROW_KEY = "function-row-key";
+ private static final String TAG_HARDWARE_DEFINED_SHORTCUT = "hardware-defined-shortcut";
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final Object mGlyphMapLock = new Object();
+ @GuardedBy("mGlyphMapLock")
+ private boolean mGlyphMapDataLoaded = false;
+ @GuardedBy("mGlyphMapLock")
+ private List<KeyGlyphMapData> mGlyphMapDataList = new ArrayList<>();
+ // Cache for already loaded glyph maps
+ @GuardedBy("mGlyphMapLock")
+ private final SparseArray<KeyGlyphMap> mGlyphMapCache = new SparseArray<>();
+
+ KeyboardGlyphManager(Context context, Looper looper) {
+ mContext = context;
+ mHandler = new Handler(looper);
+ }
+
+ void systemRunning() {
+ if (!keyboardGlyphMap()) {
+ return;
+ }
+ // Listen to new Package installations to fetch new Keyboard glyph maps
+ IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ resetMaps();
+ }
+ }, filter, null, mHandler);
+ }
+
+ @Override
+ @MainThread
+ public void onInputDeviceAdded(int deviceId) {
+ }
+
+ @Override
+ @MainThread
+ public void onInputDeviceRemoved(int deviceId) {
+ synchronized (mGlyphMapLock) {
+ mGlyphMapCache.remove(deviceId);
+ }
+ }
+
+ @Override
+ @MainThread
+ public void onInputDeviceChanged(int deviceId) {
+ }
+
+ @MainThread
+ private void resetMaps() {
+ synchronized (mGlyphMapLock) {
+ mGlyphMapDataLoaded = false;
+ mGlyphMapDataList.clear();
+ mGlyphMapCache.clear();
+ }
+ }
+
+ @NonNull
+ private List<KeyGlyphMapData> loadGlyphMapDataList() {
+ final PackageManager pm = mContext.getPackageManager();
+ List<KeyGlyphMapData> glyphMaps = new ArrayList<>();
+ Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_GLYPH_MAPS);
+ for (ResolveInfo resolveInfo : pm.queryBroadcastReceiversAsUser(intent,
+ PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, UserHandle.USER_SYSTEM)) {
+ if (resolveInfo == null || resolveInfo.activityInfo == null) {
+ continue;
+ }
+ final ActivityInfo activityInfo = resolveInfo.activityInfo;
+ KeyGlyphMapData data = getKeyboardGlyphMapsInPackage(pm, activityInfo);
+ if (data == null) {
+ continue;
+ }
+ glyphMaps.add(data);
+ }
+ return glyphMaps;
+ }
+
+ @Nullable
+ private KeyGlyphMapData getKeyboardGlyphMapsInPackage(PackageManager pm,
+ @NonNull ActivityInfo receiver) {
+ Bundle metaData = receiver.metaData;
+ if (metaData == null) {
+ return null;
+ }
+
+ int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_GLYPH_MAPS);
+ if (configResId == 0) {
+ Slog.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_GLYPH_MAPS
+ + "' on receiver " + receiver.packageName + "/" + receiver.name);
+ return null;
+ }
+
+ try {
+ Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+ try (XmlResourceParser parser = resources.getXml(configResId)) {
+ XmlUtils.beginDocument(parser, TAG_KEYBOARD_GLYPH_MAPS);
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+ String element = parser.getName();
+ if (element == null) {
+ break;
+ }
+ if (!TAG_KEYBOARD_GLYPH_MAP.equals(element)) {
+ continue;
+ }
+ TypedArray a = resources.obtainAttributes(parser, R.styleable.KeyboardGlyphMap);
+ try {
+ int glyphMapRes = a.getResourceId(R.styleable.KeyboardGlyphMap_glyphMap, 0);
+ int vendor = a.getInt(R.styleable.KeyboardGlyphMap_vendorId, -1);
+ int product = a.getInt(R.styleable.KeyboardGlyphMap_productId, -1);
+ if (glyphMapRes != 0 && vendor != -1 && product != -1) {
+ return new KeyGlyphMapData(receiver.packageName, receiver.name,
+ glyphMapRes, vendor, product);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ }
+ } catch (Exception ex) {
+ Slog.w(TAG, "Could not parse keyboard glyph map resource from receiver "
+ + receiver.packageName + "/" + receiver.name, ex);
+ }
+ return null;
+ }
+
+ @Nullable
+ private KeyGlyphMap loadGlyphMap(KeyGlyphMapData data) {
+ final PackageManager pm = mContext.getPackageManager();
+ try {
+ ComponentName componentName = new ComponentName(data.packageName, data.receiverName);
+ ActivityInfo receiver = pm.getReceiverInfo(componentName,
+ PackageManager.GET_META_DATA
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+ Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+ return loadGlyphMapFromResource(resources, componentName, data.resourceId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Package not found: " + e);
+ }
+ return null;
+ }
+
+ @NonNull
+ private KeyGlyphMap loadGlyphMapFromResource(Resources resources,
+ @NonNull ComponentName componentName, @AnyRes int glyphMapId) {
+ SparseIntArray keyGlyphs = new SparseIntArray();
+ SparseIntArray modifierGlyphs = new SparseIntArray();
+ List<Integer> functionRowKeys = new ArrayList<>();
+ HashMap<KeyGlyphMap.KeyCombination, Integer> hardwareShortcuts = new HashMap<>();
+ try {
+ XmlResourceParser parser = resources.getXml(glyphMapId);
+ XmlUtils.beginDocument(parser, TAG_KEYBOARD_GLYPH_MAP);
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+ String element = parser.getName();
+ if (element == null) {
+ break;
+ }
+ switch (element) {
+ case TAG_KEY_GLYPH -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.KeyGlyph);
+ try {
+ int keycode = a.getInt(R.styleable.KeyGlyph_keycode, 0);
+ int keyGlyph = a.getResourceId(R.styleable.KeyGlyph_glyphDrawable, 0);
+ if (keycode != 0 && keyGlyph != 0) {
+ keyGlyphs.put(keycode, keyGlyph);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ case TAG_MODIFIER_GLYPH -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.ModifierGlyph);
+ try {
+ int modifier = a.getInt(R.styleable.ModifierGlyph_modifier, 0);
+ int modifierGlyph = a.getResourceId(
+ R.styleable.ModifierGlyph_glyphDrawable,
+ 0);
+ if (modifier != 0 && modifierGlyph != 0) {
+ modifierGlyphs.put(modifier, modifierGlyph);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ case TAG_FUNCTION_ROW_KEY -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.FunctionRowKey);
+ try {
+ int keycode = a.getInt(R.styleable.FunctionRowKey_keycode, 0);
+ if (keycode != 0) {
+ functionRowKeys.add(keycode);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ case TAG_HARDWARE_DEFINED_SHORTCUT -> {
+ final TypedArray a = resources.obtainAttributes(parser,
+ R.styleable.HardwareDefinedShortcut);
+ try {
+ int keycode = a.getInt(R.styleable.HardwareDefinedShortcut_keycode,
+ 0);
+ int modifierState = a.getInt(
+ R.styleable.HardwareDefinedShortcut_modifierState, 0);
+ int outKeycode = a.getInt(
+ R.styleable.HardwareDefinedShortcut_outKeycode,
+ 0);
+ if (keycode != 0 && modifierState != 0 && outKeycode != 0) {
+ hardwareShortcuts.put(
+ new KeyGlyphMap.KeyCombination(modifierState, keycode),
+ outKeycode);
+ }
+ } finally {
+ a.recycle();
+ }
+ }
+ }
+ }
+ } catch (XmlPullParserException | IOException e) {
+ Log.e(TAG, "Unable to parse key glyph map : " + e);
+ }
+ return new KeyGlyphMap(componentName, keyGlyphs, modifierGlyphs,
+ functionRowKeys.stream().mapToInt(Integer::intValue).toArray(), hardwareShortcuts);
+ }
+
+ /**
+ * Returns keyboard glyph map corresponding to device ID
+ */
+ @Nullable
+ public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+ if (!keyboardGlyphMap()) {
+ return null;
+ }
+ synchronized (mGlyphMapLock) {
+ if (mGlyphMapCache.indexOfKey(deviceId) >= 0) {
+ return mGlyphMapCache.get(deviceId);
+ }
+ KeyGlyphMap keyGlyphMap = getKeyGlyphMapInternal(deviceId);
+ mGlyphMapCache.put(deviceId, keyGlyphMap);
+ return keyGlyphMap;
+ }
+ }
+
+ @GuardedBy("mGlyphMapLock")
+ private KeyGlyphMap getKeyGlyphMapInternal(int deviceId) {
+ final InputDevice inputDevice = getInputDevice(deviceId);
+ if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
+ return null;
+ }
+ if (!mGlyphMapDataLoaded) {
+ mGlyphMapDataList = loadGlyphMapDataList();
+ mGlyphMapDataLoaded = true;
+ }
+ for (KeyGlyphMapData data : mGlyphMapDataList) {
+ if (data.vendorId == inputDevice.getVendorId()
+ && data.productId == inputDevice.getProductId()) {
+ return loadGlyphMap(data);
+ }
+ }
+ return null;
+ }
+
+ void dump(IndentingPrintWriter ipw) {
+ if (!keyboardGlyphMap()) {
+ return;
+ }
+ List<KeyGlyphMapData> glyphMapDataList = loadGlyphMapDataList();
+ ipw.println(TAG + ": " + glyphMapDataList.size() + " glyph maps");
+ ipw.increaseIndent();
+ for (KeyGlyphMapData data : glyphMapDataList) {
+ ipw.println(data);
+ if (DEBUG) {
+ KeyGlyphMap map = loadGlyphMap(data);
+ if (map != null) {
+ ipw.increaseIndent();
+ ipw.println(map);
+ ipw.decreaseIndent();
+ }
+ }
+ }
+ ipw.decreaseIndent();
+ }
+
+ @Nullable
+ private InputDevice getInputDevice(int deviceId) {
+ InputManager inputManager = mContext.getSystemService(InputManager.class);
+ return inputManager != null ? inputManager.getInputDevice(deviceId) : null;
+ }
+
+ private record KeyGlyphMapData(@NonNull String packageName, @NonNull String receiverName,
+ @AnyRes int resourceId, int vendorId, int productId) {
+ }
+}
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 97c32b9..4993412 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -255,17 +255,6 @@
}
}
- private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) {
- // Different languages are never compatible
- if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) {
- return false;
- }
- // If both the system and the keyboard layout have a country specifier, they must be equal.
- return TextUtils.isEmpty(systemLocale.getCountry())
- || TextUtils.isEmpty(keyboardLocale.getCountry())
- || systemLocale.getCountry().equals(keyboardLocale.getCountry());
- }
-
@MainThread
private void updateKeyboardLayouts() {
// Scan all input devices state for keyboard layouts that have been uninstalled.
@@ -953,21 +942,33 @@
return;
}
+ List<String> layoutNames = new ArrayList<>();
+ for (String layoutDesc : config.getConfiguredLayouts()) {
+ KeyboardLayout kl = getKeyboardLayout(layoutDesc);
+ if (kl == null) {
+ // b/349033234: Weird state with stale keyboard layout configured.
+ // Possibly due to race condition between KCM providing package being removed and
+ // corresponding layouts being removed from Datastore and cache.
+ // {@see updateKeyboardLayouts()}
+ //
+ // Ideally notification will be correctly shown after the keyboard layouts are
+ // configured again with the new package state.
+ return;
+ }
+ layoutNames.add(kl.getLabel());
+ }
showKeyboardLayoutNotification(
r.getString(
R.string.keyboard_layout_notification_selected_title,
inputDevice.getName()),
- createConfiguredNotificationText(mContext, config.getConfiguredLayouts()),
+ createConfiguredNotificationText(mContext, layoutNames),
inputDevice);
}
@MainThread
private String createConfiguredNotificationText(@NonNull Context context,
- @NonNull Set<String> selectedLayouts) {
+ @NonNull List<String> layoutNames) {
final Resources r = context.getResources();
- List<String> layoutNames = new ArrayList<>();
- selectedLayouts.forEach(
- (layoutDesc) -> layoutNames.add(getKeyboardLayout(layoutDesc).getLabel()));
Collections.sort(layoutNames);
switch (layoutNames.size()) {
case 1:
diff --git a/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java b/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java
index 0749edc..aeace7a 100644
--- a/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java
+++ b/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java
@@ -103,8 +103,8 @@
// Note that current user ID is guaranteed to be userId.
final var imeId = mBindingController.getSelectedMethodId();
- final InputMethodInfo imi = InputMethodSettingsRepository.get(mBindingController.mUserId)
- .getMethodMap().get(imeId);
+ final InputMethodInfo imi = InputMethodSettingsRepository.get(
+ mBindingController.getUserId()).getMethodMap().get(imeId);
if (imi == null || !isInlineSuggestionsEnabled(imi, touchExplorationEnabled)) {
callback.onInlineSuggestionsUnsupported();
return;
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index b77f47d..5ff421a 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -53,10 +53,10 @@
import java.util.Objects;
/**
- * The default implementation of {@link ImeVisibilityApplier} used in
- * {@link InputMethodManagerService}.
+ * A stateless helper class for IME visibility operations like show/hide and update Z-ordering
+ * relative to the IME targeted window.
*/
-final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
+final class DefaultImeVisibilityApplier {
private static final String TAG = "DefaultImeVisibilityApplier";
@@ -75,12 +75,22 @@
mImeTargetVisibilityPolicy = LocalServices.getService(ImeTargetVisibilityPolicy.class);
}
+ /**
+ * Performs showing IME on top of the given window.
+ *
+ * @param showInputToken a token that represents the requester to show IME
+ * @param statsToken the token tracking the current IME request
+ * @param resultReceiver if non-null, this will be called back to the caller when
+ * it has processed request to tell what it has done
+ * @param reason yhe reason for requesting to show IME
+ * @param userId the target user when performing show IME
+ */
@GuardedBy("ImfLock.class")
- @Override
- public void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken,
+ void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken,
@InputMethod.ShowFlags int showFlags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason, @UserIdInt int userId) {
final var bindingController = mService.getInputMethodBindingController(userId);
+ final var userData = mService.getUserData(userId);
final IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null) {
if (DEBUG) {
@@ -93,10 +103,10 @@
if (DEBUG_IME_VISIBILITY) {
EventLog.writeEvent(IMF_SHOW_IME,
statsToken != null ? statsToken.getTag() : ImeTracker.TOKEN_NONE,
- Objects.toString(mService.mImeBindingState.mFocusedWindow),
+ Objects.toString(userData.mImeBindingState.mFocusedWindow),
InputMethodDebug.softInputDisplayReasonToString(reason),
InputMethodDebug.softInputModeToString(
- mService.mImeBindingState.mFocusedWindowSoftInputMode));
+ userData.mImeBindingState.mFocusedWindowSoftInputMode));
}
mService.onShowHideSoftInputRequested(true /* show */, showInputToken, reason,
statsToken, userId);
@@ -104,13 +114,23 @@
}
}
+ /**
+ * Performs hiding IME to the given window
+ *
+ * @param hideInputToken a token that represents the requester to hide IME
+ * @param statsToken the token tracking the current IME request
+ * @param resultReceiver if non-null, this will be called back to the caller when
+ * it has processed request to tell what it has done
+ * @param reason the reason for requesting to hide IME
+ * @param userId the target user when performing hide IME
+ */
@GuardedBy("ImfLock.class")
- @Override
- public void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken,
+ void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken,
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
@UserIdInt int userId) {
final var bindingController = mService.getInputMethodBindingController(userId);
final IInputMethodInvoker curMethod = bindingController.getCurMethod();
+ final var userData = mService.getUserData(userId);
if (curMethod != null) {
// The IME will report its visible state again after the following message finally
// delivered to the IME process as an IPC. Hence the inconsistency between
@@ -126,10 +146,10 @@
if (DEBUG_IME_VISIBILITY) {
EventLog.writeEvent(IMF_HIDE_IME,
statsToken != null ? statsToken.getTag() : ImeTracker.TOKEN_NONE,
- Objects.toString(mService.mImeBindingState.mFocusedWindow),
+ Objects.toString(userData.mImeBindingState.mFocusedWindow),
InputMethodDebug.softInputDisplayReasonToString(reason),
InputMethodDebug.softInputModeToString(
- mService.mImeBindingState.mFocusedWindowSoftInputMode));
+ userData.mImeBindingState.mFocusedWindowSoftInputMode));
}
mService.onShowHideSoftInputRequested(false /* show */, hideInputToken, reason,
statsToken, userId);
@@ -137,19 +157,22 @@
}
}
- @GuardedBy("ImfLock.class")
- @Override
- public void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
- @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) {
- applyImeVisibility(windowToken, statsToken, state,
- SoftInputShowHideReason.NOT_SET /* ignore reason */, userId);
- }
-
+ /**
+ * Applies the IME visibility from {@link android.inputmethodservice.InputMethodService} with
+ * according to the given visibility state.
+ *
+ * @param windowToken the token of a window for applying the IME visibility
+ * @param statsToken the token tracking the current IME request
+ * @param state the new IME visibility state for the applier to handle
+ * @param reason one of {@link SoftInputShowHideReason}
+ * @param userId the target user when applying the IME visibility state
+ */
@GuardedBy("ImfLock.class")
void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
@ImeVisibilityStateComputer.VisibilityState int state,
@SoftInputShowHideReason int reason, @UserIdInt int userId) {
final var bindingController = mService.getInputMethodBindingController(userId);
+ final var userData = mService.getUserData(userId);
final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
switch (state) {
case STATE_SHOW_IME:
@@ -162,7 +185,7 @@
break;
case STATE_HIDE_IME:
if (!Flags.refactorInsetsController()) {
- if (mService.hasAttachedClient()) {
+ if (userData.mCurClient != null) {
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
// IMMS only knows of focused window, not the actual IME target.
@@ -179,29 +202,30 @@
break;
case STATE_HIDE_IME_EXPLICIT:
if (Flags.refactorInsetsController()) {
- setImeVisibilityOnFocusedWindowClient(false);
+ setImeVisibilityOnFocusedWindowClient(false, userId);
} else {
mService.hideCurrentInputLocked(windowToken, statsToken,
- 0 /* flags */, null /* resultReceiver */, reason);
+ 0 /* flags */, null /* resultReceiver */, reason, userId);
}
break;
case STATE_HIDE_IME_NOT_ALWAYS:
if (Flags.refactorInsetsController()) {
- setImeVisibilityOnFocusedWindowClient(false);
+ setImeVisibilityOnFocusedWindowClient(false, userId);
} else {
mService.hideCurrentInputLocked(windowToken, statsToken,
- InputMethodManager.HIDE_NOT_ALWAYS, null /* resultReceiver */, reason);
+ InputMethodManager.HIDE_NOT_ALWAYS, null /* resultReceiver */, reason,
+ userId);
}
break;
case STATE_SHOW_IME_IMPLICIT:
if (Flags.refactorInsetsController()) {
// This can be triggered by IMMS#startInputOrWindowGainedFocus. We need to
// set the requestedVisibleTypes in InsetsController first, before applying it.
- setImeVisibilityOnFocusedWindowClient(true);
+ setImeVisibilityOnFocusedWindowClient(true, userId);
} else {
mService.showCurrentInputLocked(windowToken, statsToken,
InputMethodManager.SHOW_IMPLICIT, MotionEvent.TOOL_TYPE_UNKNOWN,
- null /* resultReceiver */, reason);
+ null /* resultReceiver */, reason, userId);
}
break;
case STATE_SHOW_IME_SNAPSHOT:
@@ -215,9 +239,16 @@
}
}
+ /**
+ * Shows the IME screenshot and attach it to the given IME target window.
+ *
+ * @param imeTarget the token of a window to show the IME screenshot
+ * @param displayId the unique id to identify the display
+ * @param userId the target user when when showing the IME screenshot
+ * @return {@code true} if success, {@code false} otherwise
+ */
@GuardedBy("ImfLock.class")
- @Override
- public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId,
+ boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId,
@UserIdInt int userId) {
if (mImeTargetVisibilityPolicy.showImeScreenshot(imeTarget, displayId)) {
mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
@@ -227,23 +258,32 @@
return false;
}
+ /**
+ * Removes the IME screenshot on the given display.
+ *
+ * @param displayId the target display of showing IME screenshot
+ * @param userId the target user of showing IME screenshot
+ * @return {@code true} if success, {@code false} otherwise
+ */
@GuardedBy("ImfLock.class")
- @Override
- public boolean removeImeScreenshot(int displayId, @UserIdInt int userId) {
+ boolean removeImeScreenshot(int displayId, @UserIdInt int userId) {
+ final var userData = mService.getUserData(userId);
if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
mService.onShowHideSoftInputRequested(false /* show */,
- mService.mImeBindingState.mFocusedWindow,
+ userData.mImeBindingState.mFocusedWindow,
REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId);
return true;
}
return false;
}
- private void setImeVisibilityOnFocusedWindowClient(boolean visibility) {
- if (mService.mImeBindingState != null
- && mService.mImeBindingState.mFocusedWindowClient != null
- && mService.mImeBindingState.mFocusedWindowClient.mClient != null) {
- mService.mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(visibility);
+ @GuardedBy("ImfLock.class")
+ private void setImeVisibilityOnFocusedWindowClient(boolean visibility, @UserIdInt int userId) {
+ final var userData = mService.getUserData(userId);
+ if (userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindowClient != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+ userData.mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(visibility);
} else {
// TODO(b/329229469): ImeTracker?
}
diff --git a/services/core/java/com/android/server/inputmethod/ImeTrackerService.java b/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
index 56fa8c9..14551a1 100644
--- a/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
+++ b/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
@@ -23,7 +23,6 @@
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.util.Log;
import android.view.inputmethod.ImeTracker;
@@ -70,8 +69,8 @@
private final Object mLock = new Object();
- ImeTrackerService(@NonNull Looper looper) {
- mHandler = new Handler(looper, null /* callback */, true /* async */);
+ ImeTrackerService(@NonNull Handler handler) {
+ mHandler = handler;
}
@NonNull
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
deleted file mode 100644
index c1069f2..0000000
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.inputmethod;
-
-import android.annotation.NonNull;
-import android.annotation.UserIdInt;
-import android.os.IBinder;
-import android.os.ResultReceiver;
-import android.view.inputmethod.ImeTracker;
-import android.view.inputmethod.InputMethod;
-
-import com.android.internal.inputmethod.SoftInputShowHideReason;
-
-/**
- * Interface for IME visibility operations like show/hide and update Z-ordering relative to the IME
- * targeted window.
- */
-interface ImeVisibilityApplier {
- /**
- * Performs showing IME on top of the given window.
- *
- * @param showInputToken a token that represents the requester to show IME
- * @param statsToken the token tracking the current IME request
- * @param resultReceiver if non-null, this will be called back to the caller when
- * it has processed request to tell what it has done
- * @param reason yhe reason for requesting to show IME
- * @param userId the target user when performing show IME
- */
- default void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken,
- @InputMethod.ShowFlags int showFlags, ResultReceiver resultReceiver,
- @SoftInputShowHideReason int reason, @UserIdInt int userId) {
- }
-
- /**
- * Performs hiding IME to the given window
- *
- * @param hideInputToken a token that represents the requester to hide IME
- * @param statsToken the token tracking the current IME request
- * @param resultReceiver if non-null, this will be called back to the caller when
- * it has processed request to tell what it has done
- * @param reason the reason for requesting to hide IME
- * @param userId the target user when performing hide IME
- */
- default void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken,
- ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
- @UserIdInt int userId) {
- }
-
- /**
- * Applies the IME visibility from {@link android.inputmethodservice.InputMethodService} with
- * according to the given visibility state.
- *
- * @param windowToken the token of a window for applying the IME visibility
- * @param statsToken the token tracking the current IME request
- * @param state the new IME visibility state for the applier to handle
- * @param userId the target user when applying the IME visibility state
- */
- default void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
- @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) {
- }
-
- /**
- * Updates the IME Z-ordering relative to the given window.
- *
- * This used to adjust the IME relative layer of the window during
- * {@link InputMethodManagerService} is in switching IME clients.
- *
- * @param windowToken the token of a window to update the Z-ordering relative to the IME
- */
- default void updateImeLayeringByTarget(IBinder windowToken) {
- // TODO: add a method in WindowManagerInternal to call DC#updateImeInputAndControlTarget
- // here to end up updating IME layering after IMMS#attachNewInputLocked called.
- }
-
- /**
- * Shows the IME screenshot and attach it to the given IME target window.
- *
- * @param windowToken the token of a window to show the IME screenshot
- * @param displayId the unique id to identify the display
- * @param userId the target user when when showing the IME screenshot
- * @return {@code true} if success, {@code false} otherwise
- */
- default boolean showImeScreenshot(@NonNull IBinder windowToken, int displayId,
- @UserIdInt int userId) {
- return false;
- }
-
- /**
- * Removes the IME screenshot on the given display.
- *
- * @param displayId the target display of showing IME screenshot
- * @param userId the target user of showing IME screenshot
- * @return {@code true} if success, {@code false} otherwise
- */
- default boolean removeImeScreenshot(int displayId, @UserIdInt int userId) {
- return false;
- }
-}
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index 9d80844..7ebf595 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -38,6 +38,7 @@
import android.accessibilityservice.AccessibilityService;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UserIdInt;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.IBinder;
@@ -52,6 +53,7 @@
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodManager;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.server.LocalServices;
@@ -553,15 +555,17 @@
return null;
}
- IBinder getWindowTokenFrom(IBinder requestImeToken) {
+ @GuardedBy("ImfLock.class")
+ IBinder getWindowTokenFrom(IBinder requestImeToken, @UserIdInt int userId) {
for (IBinder windowToken : mRequestWindowStateMap.keySet()) {
final ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
if (state.getRequestImeToken() == requestImeToken) {
return windowToken;
}
}
+ final var userData = mService.getUserData(userId);
// Fallback to the focused window for some edge cases (e.g. relaunching the activity)
- return mService.mImeBindingState.mFocusedWindow;
+ return userData.mImeBindingState.mFocusedWindow;
}
IBinder getWindowTokenFrom(ImeTargetWindowState windowState) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index 60d647d..5ab493b 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -70,7 +70,7 @@
/** Time in milliseconds that the IME service has to bind before it is reconnected. */
static final long TIME_TO_RECONNECT = 3 * 1000;
- @UserIdInt final int mUserId;
+ @UserIdInt private final int mUserId;
@NonNull private final InputMethodManagerService mService;
@NonNull private final Context mContext;
@NonNull private final AutofillSuggestionsController mAutofillController;
@@ -96,6 +96,32 @@
@GuardedBy("ImfLock.class") private int mDisplayIdToShowIme = INVALID_DISPLAY;
@GuardedBy("ImfLock.class") private int mDeviceIdToShowIme = DEVICE_ID_DEFAULT;
+ /**
+ * A set of status bits regarding the active IME.
+ *
+ * <p>This value is a combination of following two bits:</p>
+ * <dl>
+ * <dt>{@link InputMethodService#IME_ACTIVE}</dt>
+ * <dd>
+ * If this bit is ON, connected IME is ready to accept touch/key events.
+ * </dd>
+ * <dt>{@link InputMethodService#IME_VISIBLE}</dt>
+ * <dd>
+ * If this bit is ON, some of IME view, e.g. software input, candidate view, is visible.
+ * </dd>
+ * <dt>{@link InputMethodService#IME_INVISIBLE}</dt>
+ * <dd> If this bit is ON, IME is ready with views from last EditorInfo but is
+ * currently invisible.
+ * </dd>
+ * </dl>
+ * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and
+ * {@link InputMethodBindingController#unbindCurrentMethod()}.</em>
+ */
+ @GuardedBy("ImfLock.class") private int mImeWindowVis;
+
+ @GuardedBy("ImfLock.class")
+ private int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
+
@Nullable private CountDownLatch mLatchForTesting;
/**
@@ -382,9 +408,9 @@
InputMethodManager
.invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
}
- mService.initializeImeLocked(mCurMethod, mCurToken);
+ mService.initializeImeLocked(mCurMethod, mCurToken, mUserId);
mService.scheduleNotifyImeUidToAudioService(mCurMethodUid);
- mService.reRequestCurrentClientSessionLocked();
+ mService.reRequestCurrentClientSessionLocked(mUserId);
mAutofillController.performOnCreateInlineSuggestionsRequest();
}
@@ -437,7 +463,7 @@
mLastBindTime = SystemClock.uptimeMillis();
clearCurMethodAndSessions();
mService.clearInputShownLocked();
- mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME);
+ mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME, mUserId);
}
}
}
@@ -473,7 +499,7 @@
if (getCurToken() != null) {
removeCurrentToken();
- mService.resetSystemUiLocked();
+ mService.resetSystemUiLocked(this);
mAutofillController.onResetSystemUi();
}
@@ -483,7 +509,7 @@
@GuardedBy("ImfLock.class")
private void clearCurMethodAndSessions() {
- mService.clearClientSessionsLocked();
+ mService.clearClientSessionsLocked(this);
mCurMethod = null;
mCurMethodUid = Process.INVALID_UID;
}
@@ -638,6 +664,36 @@
}
}
+ /**
+ * Returns the current {@link InputMethodSubtype}.
+ *
+ * <p>Also this method has had questionable behaviors:</p>
+ * <ul>
+ * <li>Calling this method can update {@link #mCurrentSubtype}.</li>
+ * <li>This method may return {@link #mCurrentSubtype} as-is, even if it does not belong to
+ * the current IME.</li>
+ * </ul>
+ * <p>TODO(b/347083680): Address above issues.</p>
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ InputMethodSubtype getCurrentInputMethodSubtype() {
+ final var selectedMethodId = getSelectedMethodId();
+ if (selectedMethodId == null) {
+ return null;
+ }
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(mUserId);
+ final InputMethodInfo imi = settings.getMethodMap().get(selectedMethodId);
+ if (imi == null || imi.getSubtypeCount() == 0) {
+ return null;
+ }
+ final var subtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
+ mCurrentSubtype);
+ mCurrentSubtype = subtype;
+ return subtype;
+ }
+
+
@GuardedBy("ImfLock.class")
void setDisplayIdToShowIme(int displayId) {
mDisplayIdToShowIme = displayId;
@@ -657,4 +713,29 @@
int getDeviceIdToShowIme() {
return mDeviceIdToShowIme;
}
+
+ @UserIdInt
+ int getUserId() {
+ return mUserId;
+ }
+
+ @GuardedBy("ImfLock.class")
+ void setImeWindowVis(int imeWindowVis) {
+ mImeWindowVis = imeWindowVis;
+ }
+
+ @GuardedBy("ImfLock.class")
+ int getImeWindowVis() {
+ return mImeWindowVis;
+ }
+
+ @GuardedBy("ImfLock.class")
+ int getBackDisposition() {
+ return mBackDisposition;
+ }
+
+ @GuardedBy("ImfLock.class")
+ void setBackDisposition(int backDisposition) {
+ mBackDisposition = backDisposition;
+ }
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 2d77610..89b320d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -90,7 +90,6 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.LocaleList;
-import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
@@ -321,6 +320,19 @@
&& Flags.concurrentInputMethods();
}
+ /**
+ * Figures out the target IME user ID for a given {@link Binder} IPC.
+ *
+ * @param callingProcessUserId the user ID of the calling process
+ * @return User ID to be used for this {@link Binder} call.
+ */
+ @GuardedBy("ImfLock.class")
+ @UserIdInt
+ @BinderThread
+ private int resolveImeUserIdLocked(@UserIdInt int callingProcessUserId) {
+ return mExperimentalConcurrentMultiUserModeEnabled ? callingProcessUserId : mCurrentUserId;
+ }
+
final Context mContext;
final Resources mRes;
private final Handler mHandler;
@@ -468,12 +480,6 @@
private final ClientController mClientController;
/**
- * Holds the current IME binding state info.
- */
- @MultiUserUnawareField
- ImeBindingState mImeBindingState;
-
- /**
* Set once the system is ready to run third party code.
*/
@SharedByAllUsersField
@@ -491,39 +497,6 @@
return getUserData(userId).mBindingController;
}
-
- /**
- * Id obtained with {@link InputMethodInfo#getId()} for the currently selected input method.
- * This is to be synchronized with the secure settings keyed with
- * {@link Settings.Secure#DEFAULT_INPUT_METHOD}.
- *
- * <p>This can be transiently {@code null} when the system is re-initializing input method
- * settings, e.g., the system locale is just changed.</p>
- *
- * <p>Note that {@link InputMethodBindingController#getCurId()} is used to track which IME
- * is being connected to {@link InputMethodManagerService}.</p>
- *
- * @see InputMethodBindingController#getCurId()
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- String getSelectedMethodIdLocked() {
- return getInputMethodBindingController(mCurrentUserId).getSelectedMethodId();
- }
-
- @GuardedBy("ImfLock.class")
- @Nullable
- InputMethodInfo queryInputMethodForCurrentUserLocked(@NonNull String imeId) {
- return InputMethodSettingsRepository.get(mCurrentUserId).getMethodMap().get(imeId);
- }
-
- /**
- * The client that is currently bound to an input method.
- */
- @MultiUserUnawareField
- @Nullable
- private ClientState mCurClient;
-
/**
* The last window token that we confirmed that IME started talking to. This is always updated
* upon reports from the input method. If the window state is already changed before the report
@@ -533,33 +506,6 @@
IBinder mLastImeTargetWindow;
/**
- * The {@link IRemoteInputConnection} last provided by the current client.
- */
- @MultiUserUnawareField
- IRemoteInputConnection mCurInputConnection;
-
- /**
- * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to
- * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME.
- */
- @MultiUserUnawareField
- ImeOnBackInvokedDispatcher mCurImeDispatcher;
-
- /**
- * The {@link IRemoteAccessibilityInputConnection} last provided by the current client.
- */
- @MultiUserUnawareField
- @Nullable
- IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection;
-
- /**
- * The {@link EditorInfo} last provided by the current client.
- */
- @MultiUserUnawareField
- @Nullable
- EditorInfo mCurEditorInfo;
-
- /**
* Map of window perceptible states indexed by their associated window tokens.
*
* The value {@code true} indicates that IME has not been mostly hidden via
@@ -570,38 +516,6 @@
private final WeakHashMap<IBinder, Boolean> mFocusedWindowPerceptible = new WeakHashMap<>();
/**
- * The token tracking the current IME show request that is waiting for a connection to an IME,
- * otherwise {@code null}.
- */
- @Nullable
- @MultiUserUnawareField
- private ImeTracker.Token mCurStatsToken;
-
- /**
- * {@code true} if the current input method is in fullscreen mode.
- */
- @MultiUserUnawareField
- boolean mInFullscreenMode;
-
- /**
- * The token we have made for the currently active input method, to
- * identify it in the future.
- */
- @GuardedBy("ImfLock.class")
- @Nullable
- IBinder getCurTokenLocked() {
- return getInputMethodBindingController(mCurrentUserId).getCurToken();
- }
-
- /**
- * The displayId of current active input method.
- */
- @GuardedBy("ImfLock.class")
- int getCurTokenDisplayIdLocked() {
- return getInputMethodBindingController(mCurrentUserId).getCurTokenDisplayId();
- }
-
- /**
* The display ID of the input method indicates the fallback display which returned by
* {@link #computeImeDisplayIdForTarget}.
*/
@@ -618,59 +532,11 @@
}
/**
- * Have we called mCurMethod.bindInput()?
- */
- @MultiUserUnawareField
- boolean mBoundToMethod;
-
- /**
- * Have we called bindInput() for accessibility services?
- */
- @MultiUserUnawareField
- boolean mBoundToAccessibility;
-
- /**
- * Currently enabled session.
- */
- @GuardedBy("ImfLock.class")
- @MultiUserUnawareField
- SessionState mEnabledSession;
- @MultiUserUnawareField
- SparseArray<AccessibilitySessionState> mEnabledAccessibilitySessions = new SparseArray<>();
-
- /**
* True if the device is currently interactive with user. The value is true initially.
*/
@MultiUserUnawareField
boolean mIsInteractive = true;
- @MultiUserUnawareField
- int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
-
- /**
- * A set of status bits regarding the active IME.
- *
- * <p>This value is a combination of following two bits:</p>
- * <dl>
- * <dt>{@link InputMethodService#IME_ACTIVE}</dt>
- * <dd>
- * If this bit is ON, connected IME is ready to accept touch/key events.
- * </dd>
- * <dt>{@link InputMethodService#IME_VISIBLE}</dt>
- * <dd>
- * If this bit is ON, some of IME view, e.g. software input, candidate view, is visible.
- * </dd>
- * <dt>{@link InputMethodService#IME_INVISIBLE}</dt>
- * <dd> If this bit is ON, IME is ready with views from last EditorInfo but is
- * currently invisible.
- * </dd>
- * </dl>
- * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and
- * {@link InputMethodBindingController#unbindCurrentMethod()}.</em>
- */
- @MultiUserUnawareField
- int mImeWindowVis;
-
@SharedByAllUsersField
private final MyPackageMonitor mMyPackageMonitor = new MyPackageMonitor();
@@ -763,13 +629,15 @@
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, mUserId);
mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
accessibilitySoftKeyboardSetting);
+ final var userData = getUserData(mUserId);
if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE);
- } else if (isShowRequestedForCurrentWindow()) {
- showCurrentInputLocked(mImeBindingState.mFocusedWindow,
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ 0 /* flags */, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE,
+ mUserId);
+ } else if (isShowRequestedForCurrentWindow(mUserId)) {
+ showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
InputMethodManager.SHOW_IMPLICIT,
- SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE);
+ SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE, mUserId);
}
} else if (stylusHandwritingEnabledUri.equals(uri)) {
InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches();
@@ -777,13 +645,13 @@
.invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
} else {
boolean enabledChanged = false;
- String newEnabled = InputMethodSettingsRepository.get(mCurrentUserId)
+ String newEnabled = InputMethodSettingsRepository.get(mUserId)
.getEnabledInputMethodsStr();
if (!mLastEnabled.equals(newEnabled)) {
mLastEnabled = newEnabled;
enabledChanged = true;
}
- updateInputMethodsFromSettingsLocked(enabledChanged);
+ updateInputMethodsFromSettingsLocked(enabledChanged, mUserId);
}
}
}
@@ -846,10 +714,12 @@
DirectBootAwareness.AUTO);
InputMethodSettingsRepository.put(userId, settings);
}
- postInputMethodSettingUpdatedLocked(true /* resetDefaultEnabledIme */);
+ // TODO(b/305849394): Dispatch this to non-current users.
+ final int userId = mCurrentUserId;
+ postInputMethodSettingUpdatedLocked(true /* resetDefaultEnabledIme */, userId);
// If the locale is changed, needs to reset the default ime
- resetDefaultImeLocked(mContext);
- updateFromSettingsLocked(true);
+ resetDefaultImeLocked(mContext, userId);
+ updateFromSettingsLocked(true, userId);
}
}
@@ -884,8 +754,8 @@
if (!isChangingPackagesOfCurrentUserLocked()) {
return false;
}
- final InputMethodSettings settings =
- InputMethodSettingsRepository.get(mCurrentUserId);
+ final int userId = getChangingUserId();
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
String curInputMethodId = settings.getSelectedInputMethod();
final List<InputMethodInfo> methodList = settings.getMethodList();
final int numImes = methodList.size();
@@ -898,8 +768,8 @@
if (!doit) {
return true;
}
- resetSelectedInputMethodAndSubtypeLocked("");
- chooseNewDefaultIMELocked();
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
+ chooseNewDefaultIMELocked(userId);
return true;
}
}
@@ -966,7 +836,7 @@
if (change == PACKAGE_PERMANENT_CHANGE) {
Slog.i(TAG, "Input method uninstalled, disabling: " + imi.getComponent());
if (isCurrentUser) {
- setInputMethodEnabledLocked(imi.getId(), false);
+ setInputMethodEnabledLocked(imi.getId(), false, userId);
} else {
settings.buildAndPutEnabledInputMethodsStrRemovingId(
new StringBuilder(),
@@ -1004,7 +874,7 @@
if (!isCurrentUser) {
return;
}
- postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
+ postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */, userId);
boolean changed = false;
@@ -1024,12 +894,14 @@
// Uh oh, current input method is no longer around!
// Pick another one...
Slog.i(TAG, "Current input method removed: " + curInputMethodId);
- updateSystemUiLocked(0 /* vis */, mBackDisposition);
- if (!chooseNewDefaultIMELocked()) {
+ final var bindingController = getInputMethodBindingController(userId);
+ updateSystemUiLocked(0 /* vis */,
+ bindingController.getBackDisposition(), userId);
+ if (!chooseNewDefaultIMELocked(userId)) {
changed = true;
curIm = null;
Slog.i(TAG, "Unsetting current input method");
- resetSelectedInputMethodAndSubtypeLocked("");
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
}
}
}
@@ -1038,7 +910,7 @@
if (curIm == null) {
// We currently don't have a default input method... is
// one now available?
- changed = chooseNewDefaultIMELocked();
+ changed = chooseNewDefaultIMELocked(userId);
} else if (!changed && isPackageModified(curIm.getPackageName())) {
// Even if the current input method is still available, current subtype could
// be obsolete when the package is modified in practice.
@@ -1046,7 +918,7 @@
}
if (changed) {
- updateFromSettingsLocked(false);
+ updateFromSettingsLocked(false, userId);
}
}
}
@@ -1188,8 +1060,8 @@
InputMethodSettingsRepository.put(userId, newSettings);
if (mCurrentUserId == userId) {
// We need to rebuild IMEs.
- postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
- updateInputMethodsFromSettingsLocked(true /* enabledChanged */);
+ postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */, userId);
+ updateInputMethodsFromSettingsLocked(true /* enabledChanged */, userId);
} else if (mExperimentalConcurrentMultiUserModeEnabled) {
experimentalInitializeVisibleBackgroundUserLocked(userId);
}
@@ -1208,8 +1080,9 @@
}
// Hide soft input before user switch task since switch task may block main handler a while
// and delayed the hideCurrentInputLocked().
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- SoftInputShowHideReason.HIDE_SWITCH_USER);
+ final var userData = getUserData(userId);
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+ SoftInputShowHideReason.HIDE_SWITCH_USER, userId);
final UserSwitchHandlerTask task = new UserSwitchHandlerTask(this, userId,
clientToBeReset);
mUserSwitchHandlerTask = task;
@@ -1258,8 +1131,7 @@
mIoHandler = Handler.createAsync(ioThread.getLooper());
}
SystemLocaleWrapper.onStart(context, this::onActionLocaleChanged, mHandler);
- mImeTrackerService = new ImeTrackerService(serviceThreadForTesting != null
- ? serviceThreadForTesting.getLooper() : Looper.getMainLooper());
+ mImeTrackerService = new ImeTrackerService(mHandler);
// Note: SettingsObserver doesn't register observers in its constructor.
mSettingsObserver = new SettingsObserver(mHandler);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
@@ -1274,7 +1146,13 @@
mShowOngoingImeSwitcherForPhones = false;
- // InputMethodSettingsRepository should be initialized before buildInputMethodListLocked
+ // Executing InputMethodSettingsRepository.initialize() does not mean that it
+ // immediately becomes ready to return the up-to-date InputMethodSettings for each
+ // running user, because we want to return from the constructor as early as possible so
+ // as not to delay the system boot process.
+ // Search for InputMethodSettingsRepository.put() to find where and when it's actually
+ // being updated. In general IMMS should refrain from exposing the existence of IMEs
+ // until systemReady().
InputMethodSettingsRepository.initialize(mHandler, mContext);
AdditionalSubtypeMapRepository.initialize(mHandler, mContext);
@@ -1289,18 +1167,12 @@
getUserData(id);
}
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
- final var userData = getUserData(mCurrentUserId);
- userData.mSwitchingController.resetCircularListLocked(mContext, settings);
- userData.mHardwareKeyboardShortcutController.update(settings);
-
mMenuController = new InputMethodMenuController(this);
mVisibilityStateComputer = new ImeVisibilityStateComputer(this);
mVisibilityApplier = new DefaultImeVisibilityApplier(this);
mClientController = new ClientController(mPackageManagerInternal);
mClientController.addClientControllerCallback(c -> onClientRemoved(c));
- mImeBindingState = ImeBindingState.newEmptyState();
mPreventImeStartupUnlessTextEditor = mRes.getBoolean(
com.android.internal.R.bool.config_preventImeStartupUnlessTextEditor);
@@ -1349,10 +1221,11 @@
}
@GuardedBy("ImfLock.class")
- private void resetDefaultImeLocked(Context context) {
+ private void resetDefaultImeLocked(Context context, @UserIdInt int userId) {
+ final var bindingController = getInputMethodBindingController(userId);
// Do not reset the default (current) IME when it is a 3rd-party IME
- String selectedMethodId = getSelectedMethodIdLocked();
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ String selectedMethodId = bindingController.getSelectedMethodId();
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (selectedMethodId != null
&& !settings.getMethodMap().get(selectedMethodId).isSystem()) {
return;
@@ -1367,7 +1240,7 @@
if (DEBUG) {
Slog.i(TAG, "Default found, using " + defIm.getId());
}
- setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false);
+ setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false, userId);
}
@GuardedBy("ImfLock.class")
@@ -1412,22 +1285,23 @@
@GuardedBy("ImfLock.class")
private void switchUserOnHandlerLocked(@UserIdInt int newUserId,
IInputMethodClientInvoker clientToBeReset) {
+ final int prevUserId = mCurrentUserId;
if (DEBUG) {
Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
- + " currentUserId=" + mCurrentUserId);
+ + " prevUserId=" + prevUserId);
}
// Clean up stuff for mCurrentUserId, which soon becomes the previous user.
// TODO(b/338461930): Check if this is still necessary or not.
- onUnbindCurrentMethodByReset();
+ onUnbindCurrentMethodByReset(prevUserId);
// Note that in b/197848765 we want to see if we can keep the binding alive for better
// profile switching.
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ final var bindingController = getInputMethodBindingController(prevUserId);
bindingController.unbindCurrentMethod();
- unbindCurrentClientLocked(UnbindReason.SWITCH_USER);
+ unbindCurrentClientLocked(UnbindReason.SWITCH_USER, prevUserId);
// Hereafter we start initializing things for "newUserId".
@@ -1437,6 +1311,7 @@
mSettingsObserver.registerContentObserverLocked(newUserId);
mCurrentUserId = newUserId;
+ final var newUserData = getUserData(newUserId);
final String defaultImiId = SecureSettingsWrapper.getString(
Settings.Secure.DEFAULT_INPUT_METHOD, null, newUserId);
@@ -1453,13 +1328,14 @@
final boolean initialUserSwitch = TextUtils.isEmpty(defaultImiId);
final InputMethodSettings newSettings = InputMethodSettingsRepository.get(newUserId);
- postInputMethodSettingUpdatedLocked(initialUserSwitch /* resetDefaultEnabledIme */);
+ postInputMethodSettingUpdatedLocked(initialUserSwitch /* resetDefaultEnabledIme */,
+ newUserId);
if (TextUtils.isEmpty(newSettings.getSelectedInputMethod())) {
// This is the first time of the user switch and
// set the current ime to the proper one.
- resetDefaultImeLocked(mContext);
+ resetDefaultImeLocked(mContext, newUserId);
}
- updateFromSettingsLocked(true);
+ updateFromSettingsLocked(true, newUserId);
if (initialUserSwitch) {
InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
@@ -1478,7 +1354,7 @@
// The client is already gone.
return;
}
- cs.mClient.scheduleStartInputIfNecessary(mInFullscreenMode);
+ cs.mClient.scheduleStartInputIfNecessary(newUserData.mInFullscreenMode);
}
}
@@ -1496,7 +1372,9 @@
mStatusBarManagerInternal =
LocalServices.getService(StatusBarManagerInternal.class);
hideStatusBarIconLocked();
- updateSystemUiLocked(mImeWindowVis, mBackDisposition);
+ final var bindingController = getInputMethodBindingController(currentUserId);
+ updateSystemUiLocked(bindingController.getImeWindowVis(),
+ bindingController.getBackDisposition(), currentUserId);
mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
com.android.internal.R.bool.show_ongoing_ime_switcher);
if (mShowOngoingImeSwitcherForPhones) {
@@ -1540,8 +1418,8 @@
DirectBootAwareness.AUTO);
InputMethodSettingsRepository.put(currentUserId, newSettings);
postInputMethodSettingUpdatedLocked(
- !imeSelectedOnBoot /* resetDefaultEnabledIme */);
- updateFromSettingsLocked(true);
+ !imeSelectedOnBoot /* resetDefaultEnabledIme */, currentUserId);
+ updateFromSettingsLocked(true, currentUserId);
InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
getPackageManagerForUser(mContext, currentUserId),
newSettings.getEnabledInputMethodList());
@@ -1578,14 +1456,16 @@
* Returns true iff the caller is identified to be the current input method with the token.
*
* @param token the window token given to the input method when it was started
+ * @param userId userId of the calling IME process
* @return true if and only if non-null valid token is specified
*/
@GuardedBy("ImfLock.class")
- private boolean calledWithValidTokenLocked(@NonNull IBinder token) {
+ private boolean calledWithValidTokenLocked(@NonNull IBinder token, @UserIdInt int userId) {
if (token == null) {
throw new InvalidParameterException("token must not be null.");
}
- if (token != getCurTokenLocked()) {
+ final var bindingController = getInputMethodBindingController(userId);
+ if (token != bindingController.getCurToken()) {
Slog.e(TAG, "Ignoring " + Debug.getCaller() + " due to an invalid token."
+ " uid:" + Binder.getCallingUid() + " token:" + token);
return false;
@@ -1858,20 +1738,31 @@
}
}
+ @GuardedBy("ImfLock.class")
+ private void onClientRemoved(ClientState client) {
+ clearClientSessionLocked(client);
+ clearClientSessionForAccessibilityLocked(client);
+ // TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
+ @SuppressWarnings("GuardedBy") Consumer<UserDataRepository.UserData> clientRemovedForUser =
+ userData -> onClientRemovedInternalLocked(client, userData);
+ mUserDataRepository.forAllUserData(clientRemovedForUser);
+ }
+
/**
* Hide the IME if the removed user is the current user.
*/
// TODO(b/325515685): Move this method to InputMethodBindingController
@GuardedBy("ImfLock.class")
- private void onClientRemoved(ClientState client) {
- clearClientSessionLocked(client);
- clearClientSessionForAccessibilityLocked(client);
- if (mCurClient == client) {
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- SoftInputShowHideReason.HIDE_REMOVE_CLIENT);
- if (mBoundToMethod) {
- mBoundToMethod = false;
- IInputMethodInvoker curMethod = getCurMethodLocked();
+ private void onClientRemovedInternalLocked(ClientState client,
+ @NonNull UserDataRepository.UserData userData) {
+ final int userId = userData.mUserId;
+ if (userData.mCurClient == client) {
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+ SoftInputShowHideReason.HIDE_REMOVE_CLIENT, userId);
+ if (userData.mBoundToMethod) {
+ userData.mBoundToMethod = false;
+ final var userBindingController = getInputMethodBindingController(userId);
+ IInputMethodInvoker curMethod = userBindingController.getCurMethod();
if (curMethod != null) {
// When we unbind input, we are unbinding the client, so we always
// unbind ime and a11y together.
@@ -1879,10 +1770,10 @@
AccessibilityManagerInternal.get().unbindInput();
}
}
- mBoundToAccessibility = false;
- mCurClient = null;
- if (mImeBindingState.mFocusedWindowClient == client) {
- mImeBindingState = ImeBindingState.newEmptyState();
+ userData.mBoundToAccessibility = false;
+ userData.mCurClient = null;
+ if (userData.mImeBindingState.mFocusedWindowClient == client) {
+ userData.mImeBindingState = ImeBindingState.newEmptyState();
}
}
}
@@ -1895,49 +1786,51 @@
}
@GuardedBy("ImfLock.class")
- void unbindCurrentClientLocked(@UnbindReason int unbindClientReason) {
- if (mCurClient != null) {
+ void unbindCurrentClientLocked(@UnbindReason int unbindClientReason, @UserIdInt int userId) {
+ final var userData = getUserData(userId);
+ if (userData.mCurClient != null) {
if (DEBUG) {
- Slog.v(TAG, "unbindCurrentInputLocked: client=" + mCurClient.mClient.asBinder());
+ Slog.v(TAG, "unbindCurrentInputLocked: client="
+ + userData.mCurClient.mClient.asBinder());
}
- if (mBoundToMethod) {
- mBoundToMethod = false;
- IInputMethodInvoker curMethod = getCurMethodLocked();
+ final var bindingController = getInputMethodBindingController(userId);
+ if (userData.mBoundToMethod) {
+ userData.mBoundToMethod = false;
+ IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null) {
curMethod.unbindInput();
}
}
- mBoundToAccessibility = false;
+ userData.mBoundToAccessibility = false;
// Since we set active false to current client and set mCurClient to null, let's unbind
// all accessibility too. That means, when input method get disconnected (including
// switching ime), we also unbind accessibility
- mCurClient.mClient.setActive(false /* active */, false /* fullscreen */);
+ userData.mCurClient.mClient.setActive(false /* active */, false /* fullscreen */);
- // TODO(b/325515685): make binding controller user independent. Before this change, the
- // following dependencies also need to be user independent: mCurClient, mBoundToMethod,
- // getCurMethodLocked(), and mMenuController.
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
- mCurClient.mClient.onUnbindMethod(bindingController.getSequenceNumber(),
+ userData.mCurClient.mClient.onUnbindMethod(bindingController.getSequenceNumber(),
unbindClientReason);
- mCurClient.mSessionRequested = false;
- mCurClient.mSessionRequestedForAccessibility = false;
- mCurClient = null;
- ImeTracker.forLogging().onFailed(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
- mCurStatsToken = null;
+ userData.mCurClient.mSessionRequested = false;
+ userData.mCurClient.mSessionRequestedForAccessibility = false;
+ userData.mCurClient = null;
+ ImeTracker.forLogging().onFailed(userData.mCurStatsToken,
+ ImeTracker.PHASE_SERVER_WAIT_IME);
+ userData.mCurStatsToken = null;
+ // TODO: Make mMenuController multi-user aware
mMenuController.hideInputMethodMenuLocked();
}
}
/**
* TODO(b/338404383) Remove
- * Called when {@link #resetCurrentMethodAndClientLocked(int)} invoked for clean-up states
+ * Called when {@link #resetCurrentMethodAndClientLocked(int, int)} invoked for clean-up states
* before unbinding the current method.
*/
@GuardedBy("ImfLock.class")
- void onUnbindCurrentMethodByReset() {
+ void onUnbindCurrentMethodByReset(@UserIdInt int userId) {
+ final var userData = getUserData(userId);
final ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
- mImeBindingState.mFocusedWindow);
+ userData.mImeBindingState.mFocusedWindow);
if (winState != null && !winState.isRequestedImeVisible()
&& !mVisibilityStateComputer.isInputShown()) {
// Normally, the focus window will apply the IME visibility state to
@@ -1948,25 +1841,17 @@
// As a result, we have to notify WM to apply IME visibility before clearing the
// binding states in the first place.
final var statsToken = createStatsTokenForFocusedClient(false /* show */,
- SoftInputShowHideReason.UNBIND_CURRENT_METHOD);
- mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
- STATE_HIDE_IME, mCurrentUserId);
+ SoftInputShowHideReason.UNBIND_CURRENT_METHOD, userId);
+ mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
+ statsToken, STATE_HIDE_IME, SoftInputShowHideReason.NOT_SET /* ignore reason */,
+ userId);
}
}
- /**
- * {@code true} when a {@link ClientState} has attached from starting the
- * input connection.
- */
- @GuardedBy("ImfLock.class")
- boolean hasAttachedClient() {
- return mCurClient != null;
- }
-
@VisibleForTesting
void setAttachedClientForTesting(@NonNull ClientState cs) {
synchronized (ImfLock.class) {
- mCurClient = cs;
+ getUserData(mCurrentUserId).mCurClient = cs;
}
}
@@ -1982,32 +1867,36 @@
}
@GuardedBy("ImfLock.class")
- private boolean isShowRequestedForCurrentWindow() {
+ private boolean isShowRequestedForCurrentWindow(@UserIdInt int userId) {
+ final var userData = getUserData(userId);
+ // TODO(b/349904272): Make mVisibilityStateComputer multi-user aware
final ImeTargetWindowState state = mVisibilityStateComputer.getWindowStateOrNull(
- mImeBindingState.mFocusedWindow);
+ userData.mImeBindingState.mFocusedWindow);
return state != null && state.isRequestedImeVisible();
}
@GuardedBy("ImfLock.class")
@NonNull
- InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
- final int userId = mCurrentUserId;
+ InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial,
+ @UserIdInt int userId) {
final var bindingController = getInputMethodBindingController(userId);
- if (!mBoundToMethod) {
- bindingController.getCurMethod().bindInput(mCurClient.mBinding);
- mBoundToMethod = true;
+ final var userData = getUserData(userId);
+ if (!userData.mBoundToMethod) {
+ bindingController.getCurMethod().bindInput(userData.mCurClient.mBinding);
+ userData.mBoundToMethod = true;
}
final boolean restarting = !initial;
final Binder startInputToken = new Binder();
- final StartInputInfo info = new StartInputInfo(mCurrentUserId,
+ final StartInputInfo info = new StartInputInfo(userId,
bindingController.getCurToken(), bindingController.getCurTokenDisplayId(),
bindingController.getCurId(), startInputReason,
- restarting, UserHandle.getUserId(mCurClient.mUid),
- mCurClient.mSelfReportedDisplayId, mImeBindingState.mFocusedWindow, mCurEditorInfo,
- mImeBindingState.mFocusedWindowSoftInputMode,
+ restarting, UserHandle.getUserId(userData.mCurClient.mUid),
+ userData.mCurClient.mSelfReportedDisplayId,
+ userData.mImeBindingState.mFocusedWindow, userData.mCurEditorInfo,
+ userData.mImeBindingState.mFocusedWindowSoftInputMode,
bindingController.getSequenceNumber());
- mImeTargetWindowMap.put(startInputToken, mImeBindingState.mFocusedWindow);
+ mImeTargetWindowMap.put(startInputToken, userData.mImeBindingState.mFocusedWindow);
mStartInputHistory.addEntry(info);
// Seems that PackageManagerInternal#grantImplicitAccess() doesn't handle cross-user
@@ -2015,33 +1904,34 @@
// same-user scenarios.
// That said ignoring cross-user scenario will never affect IMEs that do not have
// INTERACT_ACROSS_USERS(_FULL) permissions, which is actually almost always the case.
- if (userId == UserHandle.getUserId(mCurClient.mUid)) {
+ if (userId == UserHandle.getUserId(userData.mCurClient.mUid)) {
mPackageManagerInternal.grantImplicitAccess(userId, null /* intent */,
UserHandle.getAppId(bindingController.getCurMethodUid()),
- mCurClient.mUid, true /* direct */);
+ userData.mCurClient.mUid, true /* direct */);
}
@InputMethodNavButtonFlags final int navButtonFlags = getInputMethodNavButtonFlagsLocked();
- final SessionState session = mCurClient.mCurSession;
- setEnabledSessionLocked(session);
- session.mMethod.startInput(startInputToken, mCurInputConnection, mCurEditorInfo, restarting,
- navButtonFlags, mCurImeDispatcher);
+ final SessionState session = userData.mCurClient.mCurSession;
+ setEnabledSessionLocked(session, userData);
+ session.mMethod.startInput(startInputToken, userData.mCurInputConnection,
+ userData.mCurEditorInfo, restarting, navButtonFlags, userData.mCurImeDispatcher);
if (Flags.refactorInsetsController()) {
- if (isShowRequestedForCurrentWindow() && mImeBindingState != null
- && mImeBindingState.mFocusedWindow != null) {
- showSoftInputInternal(mImeBindingState.mFocusedWindow);
+ if (isShowRequestedForCurrentWindow(userId) && userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindow != null) {
+ showSoftInputInternal(userData.mImeBindingState.mFocusedWindow);
}
} else {
- if (isShowRequestedForCurrentWindow()) {
+ if (isShowRequestedForCurrentWindow(userId)) {
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
// Re-use current statsToken, if it exists.
- final var statsToken = mCurStatsToken != null ? mCurStatsToken
+ final var statsToken = userData.mCurStatsToken != null ? userData.mCurStatsToken
: createStatsTokenForFocusedClient(true /* show */,
- SoftInputShowHideReason.ATTACH_NEW_INPUT);
- mCurStatsToken = null;
- showCurrentInputLocked(mImeBindingState.mFocusedWindow, statsToken,
+ SoftInputShowHideReason.ATTACH_NEW_INPUT, userId);
+ userData.mCurStatsToken = null;
+ showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, statsToken,
mVisibilityStateComputer.getShowFlags(), MotionEvent.TOOL_TYPE_UNKNOWN,
- null /* resultReceiver */, SoftInputShowHideReason.ATTACH_NEW_INPUT);
+ null /* resultReceiver */, SoftInputShowHideReason.ATTACH_NEW_INPUT,
+ userId);
}
}
@@ -2051,7 +1941,8 @@
final boolean suppressesSpellChecker =
curInputMethodInfo != null && curInputMethodInfo.suppressesSpellChecker();
final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions =
- createAccessibilityInputMethodSessions(mCurClient.mAccessibilitySessions);
+ createAccessibilityInputMethodSessions(
+ userData.mCurClient.mAccessibilitySessions);
if (bindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) {
mHwController.setInkWindowInitializer(new InkWindowInitializer());
}
@@ -2063,10 +1954,12 @@
@GuardedBy("ImfLock.class")
private void attachNewAccessibilityLocked(@StartInputReason int startInputReason,
- boolean initial) {
- if (!mBoundToAccessibility) {
+ boolean initial, @UserIdInt int userId) {
+ final var userData = getUserData(userId);
+
+ if (!userData.mBoundToAccessibility) {
AccessibilityManagerInternal.get().bindInput();
- mBoundToAccessibility = true;
+ userData.mBoundToAccessibility = true;
}
// TODO(b/187453053): grantImplicitAccess to accessibility services access? if so, need to
@@ -2075,9 +1968,11 @@
// We don't start input when session for a11y is created. We start input when
// input method start input, a11y manager service is always on.
if (startInputReason != StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY) {
- setEnabledSessionForAccessibilityLocked(mCurClient.mAccessibilitySessions);
- AccessibilityManagerInternal.get().startInput(mCurRemoteAccessibilityInputConnection,
- mCurEditorInfo, !initial /* restarting */);
+ setEnabledSessionForAccessibilityLocked(userData.mCurClient.mAccessibilitySessions,
+ userData);
+ AccessibilityManagerInternal.get().startInput(
+ userData.mCurRemoteAccessibilityInputConnection,
+ userData.mCurEditorInfo, !initial /* restarting */);
}
}
@@ -2113,10 +2008,13 @@
@NonNull ImeOnBackInvokedDispatcher imeDispatcher,
@NonNull InputMethodBindingController bindingController) {
+ final int userId = bindingController.getUserId();
+ final var userData = getUserData(userId);
+
// Compute the final shown display ID with validated cs.selfReportedDisplayId for this
// session & other conditions.
ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
- mImeBindingState.mFocusedWindow);
+ userData.mImeBindingState.mFocusedWindow);
if (winState == null) {
return InputBindResult.NOT_IME_TARGET_WINDOW;
}
@@ -2127,19 +2025,19 @@
// Potentially override the selected input method if the new display belongs to a virtual
// device with a custom IME.
String selectedMethodId = bindingController.getSelectedMethodId();
- final String deviceMethodId = computeCurrentDeviceMethodIdLocked(bindingController.mUserId,
- selectedMethodId);
+ final String deviceMethodId = computeCurrentDeviceMethodIdLocked(
+ bindingController.getUserId(), selectedMethodId);
if (deviceMethodId == null) {
mVisibilityStateComputer.getImePolicy().setImeHiddenByDisplayPolicy(true);
} else if (!Objects.equals(deviceMethodId, selectedMethodId)) {
setInputMethodLocked(deviceMethodId, NOT_A_SUBTYPE_ID,
- bindingController.getDeviceIdToShowIme());
+ bindingController.getDeviceIdToShowIme(), userId);
selectedMethodId = deviceMethodId;
}
if (mVisibilityStateComputer.getImePolicy().isImeHiddenByDisplayPolicy()) {
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE);
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+ SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE, userId);
return InputBindResult.NO_IME;
}
@@ -2148,19 +2046,19 @@
return InputBindResult.NO_IME;
}
- if (mCurClient != cs) {
- prepareClientSwitchLocked(cs);
+ if (userData.mCurClient != cs) {
+ prepareClientSwitchLocked(cs, userId);
}
- final boolean connectionWasActive = mCurInputConnection != null;
+ final boolean connectionWasActive = userData.mCurInputConnection != null;
// Bump up the sequence for this client and attach it.
bindingController.advanceSequenceNumber();
- mCurClient = cs;
- mCurInputConnection = inputConnection;
- mCurRemoteAccessibilityInputConnection = remoteAccessibilityInputConnection;
- mCurImeDispatcher = imeDispatcher;
+ userData.mCurClient = cs;
+ userData.mCurInputConnection = inputConnection;
+ userData.mCurRemoteAccessibilityInputConnection = remoteAccessibilityInputConnection;
+ userData.mCurImeDispatcher = imeDispatcher;
// Override the locale hints if the app is running on a virtual device.
if (mVdmInternal == null) {
mVdmInternal = LocalServices.getService(VirtualDeviceManagerInternal.class);
@@ -2171,17 +2069,17 @@
editorInfo.hintLocales = hintsFromVirtualDevice;
}
}
- mCurEditorInfo = editorInfo;
+ userData.mCurEditorInfo = editorInfo;
// Notify input manager if the connection state changes.
- final boolean connectionIsActive = mCurInputConnection != null;
+ final boolean connectionIsActive = userData.mCurInputConnection != null;
if (connectionIsActive != connectionWasActive) {
mInputManagerInternal.notifyInputMethodConnectionActive(connectionIsActive);
}
// If configured, we want to avoid starting up the IME if it is not supposed to be showing
if (shouldPreventImeStartupLocked(selectedMethodId, startInputFlags,
- unverifiedTargetSdkVersion)) {
+ unverifiedTargetSdkVersion, userId)) {
if (DEBUG) {
Slog.d(TAG, "Avoiding IME startup and unbinding current input method.");
}
@@ -2196,7 +2094,7 @@
final String curId = bindingController.getCurId();
final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
if (curId != null && curId.equals(bindingController.getSelectedMethodId())
- && displayIdToShowIme == getCurTokenDisplayIdLocked()) {
+ && displayIdToShowIme == bindingController.getCurTokenDisplayId()) {
if (cs.mCurSession != null) {
// Fast case: if we are already connected to the input method,
// then just return it.
@@ -2210,12 +2108,12 @@
// we can always attach to accessibility because AccessibilityManagerService is
// always on.
attachNewAccessibilityLocked(startInputReason,
- (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0);
+ (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0, userId);
return attachNewInputLocked(startInputReason,
- (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0);
+ (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0, userId);
}
- InputBindResult bindResult = tryReuseConnectionLocked(bindingController, cs);
+ InputBindResult bindResult = tryReuseConnectionLocked(bindingController, cs, userId);
if (bindResult != null) {
return bindResult;
}
@@ -2292,18 +2190,19 @@
private boolean shouldPreventImeStartupLocked(
@NonNull String selectedMethodId,
@StartInputFlags int startInputFlags,
- int unverifiedTargetSdkVersion) {
+ int unverifiedTargetSdkVersion,
+ @UserIdInt int userId) {
// Fast-path for the majority of cases
if (!mPreventImeStartupUnlessTextEditor) {
return false;
}
- if (isShowRequestedForCurrentWindow()) {
+ if (isShowRequestedForCurrentWindow(userId)) {
return false;
}
if (isSoftInputModeStateVisibleAllowed(unverifiedTargetSdkVersion, startInputFlags)) {
return false;
}
- final InputMethodInfo imi = InputMethodSettingsRepository.get(mCurrentUserId)
+ final InputMethodInfo imi = InputMethodSettingsRepository.get(userId)
.getMethodMap().get(selectedMethodId);
if (imi == null) {
return false;
@@ -2315,10 +2214,10 @@
}
@GuardedBy("ImfLock.class")
- private void prepareClientSwitchLocked(ClientState cs) {
+ private void prepareClientSwitchLocked(ClientState cs, @UserIdInt int userId) {
// If the client is changing, we need to switch over to the new
// one.
- unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT);
+ unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT, userId);
// If the screen is on, inform the new client it is active
if (mIsInteractive) {
cs.mClient.setActive(true /* active */, false /* fullscreen */);
@@ -2328,13 +2227,14 @@
@GuardedBy("ImfLock.class")
@Nullable
private InputBindResult tryReuseConnectionLocked(
- @NonNull InputMethodBindingController bindingController, @NonNull ClientState cs) {
+ @NonNull InputMethodBindingController bindingController, @NonNull ClientState cs,
+ @UserIdInt int userId) {
if (bindingController.hasMainConnection()) {
- if (getCurMethodLocked() != null) {
+ if (bindingController.getCurMethod() != null) {
if (!Flags.useZeroJankProxy()) {
// Return to client, and we will get back with it when
// we have had a session made for it.
- requestClientSessionLocked(cs);
+ requestClientSessionLocked(cs, userId);
requestClientSessionForAccessibilityLocked(cs);
}
return new InputBindResult(
@@ -2360,7 +2260,7 @@
bindingController.getSequenceNumber(), false);
} else {
EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME,
- getSelectedMethodIdLocked(), bindingDuration, 0);
+ bindingController.getSelectedMethodId(), bindingDuration, 0);
}
}
}
@@ -2401,12 +2301,15 @@
}
@GuardedBy("ImfLock.class")
- void initializeImeLocked(@NonNull IInputMethodInvoker inputMethod, @NonNull IBinder token) {
+ void initializeImeLocked(@NonNull IInputMethodInvoker inputMethod, @NonNull IBinder token,
+ @UserIdInt int userId) {
if (DEBUG) {
Slog.v(TAG, "Sending attach of token: " + token + " for display: "
- + getCurTokenDisplayIdLocked());
+ + getInputMethodBindingController(userId).getCurTokenDisplayId());
}
- inputMethod.initializeInternal(token, new InputMethodPrivilegedOperationsImpl(this, token),
+ inputMethod.initializeInternal(token,
+ new InputMethodPrivilegedOperationsImpl(this, token, userId),
+ // TODO(b/345519864): Make getInputMethodNavButtonFlagsLocked() multi-user aware
getInputMethodNavButtonFlagsLocked());
}
@@ -2437,7 +2340,7 @@
@BinderThread
void onSessionCreated(IInputMethodInvoker method, IInputMethodSession session,
- InputChannel channel) {
+ InputChannel channel, @UserIdInt int userId) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.onSessionCreated");
try {
synchronized (ImfLock.class) {
@@ -2447,18 +2350,21 @@
channel.dispose();
return;
}
- IInputMethodInvoker curMethod = getCurMethodLocked();
+ final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
+ IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null && method != null
&& curMethod.asBinder() == method.asBinder()) {
- if (mCurClient != null) {
- clearClientSessionLocked(mCurClient);
- mCurClient.mCurSession = new SessionState(
- mCurClient, method, session, channel);
+ if (userData.mCurClient != null) {
+ clearClientSessionLocked(userData.mCurClient);
+ userData.mCurClient.mCurSession = new SessionState(
+ userData.mCurClient, method, session, channel);
InputBindResult res = attachNewInputLocked(
- StartInputReason.SESSION_CREATED_BY_IME, true);
- attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_IME, true);
+ StartInputReason.SESSION_CREATED_BY_IME, true, userId);
+ attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_IME, true,
+ userId);
if (res.method != null) {
- mCurClient.mClient.onBindMethod(res);
+ userData.mCurClient.mClient.onBindMethod(res);
}
return;
}
@@ -2473,37 +2379,41 @@
}
@GuardedBy("ImfLock.class")
- void resetSystemUiLocked() {
+ void resetSystemUiLocked(InputMethodBindingController bindingController) {
// Set IME window status as invisible when unbinding current method.
- mImeWindowVis = 0;
- mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
- updateSystemUiLocked(mImeWindowVis, mBackDisposition);
+ final int imeWindowVis = 0;
+ final int backDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
+ bindingController.setImeWindowVis(imeWindowVis);
+ bindingController.setBackDisposition(backDisposition);
+ updateSystemUiLocked(imeWindowVis, backDisposition, bindingController.getUserId());
}
@GuardedBy("ImfLock.class")
- void resetCurrentMethodAndClientLocked(@UnbindReason int unbindClientReason) {
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ void resetCurrentMethodAndClientLocked(@UnbindReason int unbindClientReason,
+ @UserIdInt int userId) {
+ final var bindingController = getInputMethodBindingController(userId);
bindingController.setSelectedMethodId(null);
// Callback before clean-up binding states.
// TODO(b/338461930): Check if this is still necessary or not.
- onUnbindCurrentMethodByReset();
+ onUnbindCurrentMethodByReset(userId);
bindingController.unbindCurrentMethod();
- unbindCurrentClientLocked(unbindClientReason);
+ unbindCurrentClientLocked(unbindClientReason, userId);
}
@GuardedBy("ImfLock.class")
- void reRequestCurrentClientSessionLocked() {
- if (mCurClient != null) {
- clearClientSessionLocked(mCurClient);
- clearClientSessionForAccessibilityLocked(mCurClient);
- requestClientSessionLocked(mCurClient);
- requestClientSessionForAccessibilityLocked(mCurClient);
+ void reRequestCurrentClientSessionLocked(@UserIdInt int userId) {
+ final var userData = getUserData(userId);
+ if (userData.mCurClient != null) {
+ clearClientSessionLocked(userData.mCurClient);
+ clearClientSessionForAccessibilityLocked(userData.mCurClient);
+ requestClientSessionLocked(userData.mCurClient, userId);
+ requestClientSessionForAccessibilityLocked(userData.mCurClient);
}
}
@GuardedBy("ImfLock.class")
- void requestClientSessionLocked(ClientState cs) {
+ void requestClientSessionLocked(ClientState cs, @UserIdInt int userId) {
if (!cs.mSessionRequested) {
if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs);
final InputChannel serverChannel;
@@ -2516,14 +2426,15 @@
cs.mSessionRequested = true;
- final IInputMethodInvoker curMethod = getCurMethodLocked();
+ final var bindingController = getInputMethodBindingController(userId);
+ final IInputMethodInvoker curMethod = bindingController.getCurMethod();
final IInputMethodSessionCallback.Stub callback =
new IInputMethodSessionCallback.Stub() {
@Override
public void sessionCreated(IInputMethodSession session) {
final long ident = Binder.clearCallingIdentity();
try {
- onSessionCreated(curMethod, session, serverChannel);
+ onSessionCreated(curMethod, session, serverChannel, userId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -2588,7 +2499,12 @@
sessionState.mSession.finishSession();
} catch (RemoteException e) {
Slog.w(TAG, "Session failed to close due to remote exception", e);
- updateSystemUiLocked(0 /* vis */, mBackDisposition);
+ // TODO(b/350386877): Propagate userId from the caller or infer it from
+ // sessionState
+ final int userId = mCurrentUserId;
+ final var bindingController = getInputMethodBindingController(userId);
+ updateSystemUiLocked(0 /* vis */, bindingController.getBackDisposition(),
+ userId);
}
sessionState.mSession = null;
}
@@ -2614,33 +2530,42 @@
}
@GuardedBy("ImfLock.class")
- void clearClientSessionsLocked() {
- if (getCurMethodLocked() != null) {
+ void clearClientSessionsLocked(@NonNull InputMethodBindingController bindingController) {
+ final int userId = bindingController.getUserId();
+ final var userData = getUserData(userId);
+ if (bindingController.getCurMethod() != null) {
// TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
@SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession = c -> {
- clearClientSessionLocked(c);
- clearClientSessionForAccessibilityLocked(c);
+ // TODO(b/305849394): Figure out what we should do for single user IME mode.
+ final boolean shouldClearClientSession =
+ !mExperimentalConcurrentMultiUserModeEnabled
+ || UserHandle.getUserId(c.mUid) == userId;
+ if (shouldClearClientSession) {
+ clearClientSessionLocked(c);
+ clearClientSessionForAccessibilityLocked(c);
+ }
};
mClientController.forAllClients(clearClientSession);
- finishSessionLocked(mEnabledSession);
- for (int i = 0; i < mEnabledAccessibilitySessions.size(); i++) {
- finishSessionForAccessibilityLocked(mEnabledAccessibilitySessions.valueAt(i));
+ finishSessionLocked(userData.mEnabledSession);
+ for (int i = 0; i < userData.mEnabledAccessibilitySessions.size(); i++) {
+ finishSessionForAccessibilityLocked(
+ userData.mEnabledAccessibilitySessions.valueAt(i));
}
- mEnabledSession = null;
- mEnabledAccessibilitySessions.clear();
+ userData.mEnabledSession = null;
+ userData.mEnabledAccessibilitySessions.clear();
scheduleNotifyImeUidToAudioService(Process.INVALID_UID);
}
hideStatusBarIconLocked();
- mInFullscreenMode = false;
+ getUserData(userId).mInFullscreenMode = false;
mWindowManagerInternal.setDismissImeOnBackKeyPressed(false);
}
@BinderThread
private void updateStatusIcon(@NonNull IBinder token, String packageName,
- @DrawableRes int iconId) {
+ @DrawableRes int iconId, @UserIdInt int userId) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return;
}
final long ident = Binder.clearCallingIdentity();
@@ -2651,7 +2576,7 @@
} else if (packageName != null) {
if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
final PackageManager userAwarePackageManager =
- getPackageManagerForUser(mContext, mCurrentUserId);
+ getPackageManagerForUser(mContext, userId);
ApplicationInfo applicationInfo = null;
try {
applicationInfo = userAwarePackageManager.getApplicationInfo(packageName,
@@ -2684,6 +2609,9 @@
@GuardedBy("ImfLock.class")
@InputMethodNavButtonFlags
private int getInputMethodNavButtonFlagsLocked() {
+ // TODO(b/345519864): Make mImeDrawsImeNavBarRes multi-user aware.
+ final int userId = mCurrentUserId;
+ final var bindingController = getInputMethodBindingController(userId);
if (mImeDrawsImeNavBarResLazyInitFuture != null) {
// TODO(b/225366708): Avoid Future.get(), which is internally used here.
ConcurrentUtils.waitForFutureNoInterrupt(mImeDrawsImeNavBarResLazyInitFuture,
@@ -2691,15 +2619,14 @@
}
// Whether the current display has a navigation bar. When this is false (e.g. emulator),
// the IME should not draw the IME navigation bar.
- final int tokenDisplayId = getCurTokenDisplayIdLocked();
+ final int tokenDisplayId = bindingController.getCurTokenDisplayId();
final boolean hasNavigationBar = mWindowManagerInternal
.hasNavigationBar(tokenDisplayId != INVALID_DISPLAY
? tokenDisplayId : DEFAULT_DISPLAY);
final boolean canImeDrawsImeNavBar =
mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get() && hasNavigationBar;
final boolean shouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherLocked(
- InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE,
- mCurrentUserId);
+ InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE, userId);
return (canImeDrawsImeNavBar ? InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR : 0)
| (shouldShowImeSwitcherWhenImeIsShown
? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
@@ -2782,24 +2709,26 @@
@BinderThread
@SuppressWarnings("deprecation")
- private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition) {
+ private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition,
+ @UserIdInt int userId) {
final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId();
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return;
}
+ final var bindingController = getInputMethodBindingController(userId);
// Skip update IME status when current token display is not same as focused display.
// Note that we still need to update IME status when focusing external display
// that does not support system decoration and fallback to show IME on default
// display since it is intentional behavior.
- final int tokenDisplayId = getCurTokenDisplayIdLocked();
+ final int tokenDisplayId = bindingController.getCurTokenDisplayId();
if (tokenDisplayId != topFocusedDisplayId && tokenDisplayId != FALLBACK_DISPLAY_ID) {
return;
}
- mImeWindowVis = vis;
- mBackDisposition = backDisposition;
- updateSystemUiLocked(vis, backDisposition);
+ bindingController.setImeWindowVis(vis);
+ bindingController.setBackDisposition(backDisposition);
+ updateSystemUiLocked(vis, backDisposition, userId);
}
final boolean dismissImeOnBackKeyPressed;
@@ -2819,9 +2748,10 @@
}
@BinderThread
- private void reportStartInput(@NonNull IBinder token, IBinder startInputToken) {
+ private void reportStartInput(@NonNull IBinder token, IBinder startInputToken,
+ @UserIdInt int userId) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return;
}
final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken);
@@ -2834,28 +2764,29 @@
private void updateImeWindowStatus(boolean disableImeIcon) {
synchronized (ImfLock.class) {
+ // TODO(b/350386877): Propagate userId from the caller.
+ final int userId = mCurrentUserId;
if (disableImeIcon) {
- updateSystemUiLocked(0, mBackDisposition);
+ final var bindingController = getInputMethodBindingController(userId);
+ updateSystemUiLocked(0, bindingController.getBackDisposition(), userId);
} else {
- updateSystemUiLocked();
+ updateSystemUiLocked(userId);
}
}
}
- @GuardedBy("ImfLock.class")
- void updateSystemUiLocked() {
- updateSystemUiLocked(mImeWindowVis, mBackDisposition);
- }
-
// Caution! This method is called in this class. Handle multi-user carefully
@GuardedBy("ImfLock.class")
- private void updateSystemUiLocked(int vis, int backDisposition) {
- updateSystemUiLocked(vis, backDisposition, mCurrentUserId);
+ void updateSystemUiLocked(@UserIdInt int userId) {
+ final var bindingController = getInputMethodBindingController(userId);
+ updateSystemUiLocked(bindingController.getImeWindowVis(),
+ bindingController.getBackDisposition(), userId);
}
@GuardedBy("ImfLock.class")
private void updateSystemUiLocked(int vis, int backDisposition, @UserIdInt int userId) {
final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
final var curToken = bindingController.getCurToken();
if (curToken == null) {
return;
@@ -2867,8 +2798,8 @@
+ " inv: " + (vis & InputMethodService.IME_INVISIBLE)
+ " displayId: " + curTokenDisplayId);
}
- final IBinder focusedWindowToken = mImeBindingState != null
- ? mImeBindingState.mFocusedWindow : null;
+ final IBinder focusedWindowToken = userData.mImeBindingState != null
+ ? userData.mImeBindingState.mFocusedWindow : null;
final Boolean windowPerceptible = focusedWindowToken != null
? mFocusedWindowPerceptible.get(focusedWindowToken) : null;
@@ -2903,8 +2834,8 @@
}
@GuardedBy("ImfLock.class")
- void updateFromSettingsLocked(boolean enabledMayChange) {
- updateInputMethodsFromSettingsLocked(enabledMayChange);
+ void updateFromSettingsLocked(boolean enabledMayChange, @UserIdInt int userId) {
+ updateInputMethodsFromSettingsLocked(enabledMayChange, userId);
mMenuController.updateKeyboardFromSettingsLocked();
}
@@ -2914,7 +2845,7 @@
*
* <p>Never assume what this method is doing is officially supported. For the canonical and
* desired behaviors always refer to single-user code paths such as
- * {@link #updateInputMethodsFromSettingsLocked(boolean)}.</p>
+ * {@link #updateInputMethodsFromSettingsLocked(boolean, int)}.</p>
*
* <p>Here are examples of missing features.</p>
* <ul>
@@ -2960,11 +2891,13 @@
final var userData = getUserData(userId);
userData.mSwitchingController.resetCircularListLocked(mContext, settings);
userData.mHardwareKeyboardShortcutController.update(settings);
+
+ final var bindingController = getInputMethodBindingController(userId);
+ bindingController.setSelectedMethodId(id);
}
@GuardedBy("ImfLock.class")
- void updateInputMethodsFromSettingsLocked(boolean enabledMayChange) {
- final int userId = mCurrentUserId;
+ void updateInputMethodsFromSettingsLocked(boolean enabledMayChange, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (enabledMayChange) {
final PackageManager userAwarePackageManager = getPackageManagerForUser(mContext,
@@ -2995,7 +2928,7 @@
}
}
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ final var bindingController = getInputMethodBindingController(userId);
if (bindingController.getDeviceIdToShowIme() == DEVICE_ID_DEFAULT) {
String ime = SecureSettingsWrapper.getString(
Settings.Secure.DEFAULT_INPUT_METHOD, null, userId);
@@ -3020,19 +2953,19 @@
// enabled.
String id = settings.getSelectedInputMethod();
// There is no input method selected, try to choose new applicable input method.
- if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked()) {
+ if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked(userId)) {
id = settings.getSelectedInputMethod();
}
if (!TextUtils.isEmpty(id)) {
try {
- setInputMethodLocked(id, settings.getSelectedInputMethodSubtypeId(id));
+ setInputMethodLocked(id, settings.getSelectedInputMethodSubtypeId(id), userId);
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Unknown input method from prefs: " + id, e);
- resetCurrentMethodAndClientLocked(UnbindReason.SWITCH_IME_FAILED);
+ resetCurrentMethodAndClientLocked(UnbindReason.SWITCH_IME_FAILED, userId);
}
} else {
// There is no longer an input method set, so stop any current one.
- resetCurrentMethodAndClientLocked(UnbindReason.NO_IME);
+ resetCurrentMethodAndClientLocked(UnbindReason.NO_IME, userId);
}
final var userData = getUserData(userId);
@@ -3054,13 +2987,12 @@
}
@GuardedBy("ImfLock.class")
- void setInputMethodLocked(String id, int subtypeId) {
- setInputMethodLocked(id, subtypeId, DEVICE_ID_DEFAULT);
+ void setInputMethodLocked(String id, int subtypeId, @UserIdInt int userId) {
+ setInputMethodLocked(id, subtypeId, DEVICE_ID_DEFAULT, userId);
}
@GuardedBy("ImfLock.class")
- void setInputMethodLocked(String id, int subtypeId, int deviceId) {
- final int userId = mCurrentUserId;
+ void setInputMethodLocked(String id, int subtypeId, int deviceId, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
InputMethodInfo info = settings.getMethodMap().get(id);
if (info == null) {
@@ -3084,7 +3016,7 @@
// getCurrentInputMethodSubtype.
subtypeId = NOT_A_SUBTYPE_ID;
// TODO(b/347083680): The method below has questionable behaviors.
- newSubtype = getCurrentInputMethodSubtypeLocked();
+ newSubtype = bindingController.getCurrentInputMethodSubtype();
if (newSubtype != null) {
for (int i = 0; i < subtypeCount; ++i) {
if (Objects.equals(newSubtype, info.getSubtypeAt(i))) {
@@ -3095,10 +3027,11 @@
}
}
if (!Objects.equals(newSubtype, oldSubtype)) {
- setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true);
- IInputMethodInvoker curMethod = getCurMethodLocked();
+ setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true, userId);
+ IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null) {
- updateSystemUiLocked(mImeWindowVis, mBackDisposition);
+ updateSystemUiLocked(bindingController.getImeWindowVis(),
+ bindingController.getBackDisposition(), userId);
curMethod.changeInputMethodSubtype(newSubtype);
}
}
@@ -3115,7 +3048,7 @@
settings.putSelectedDefaultDeviceInputMethod(id);
return;
}
- IInputMethodInvoker curMethod = getCurMethodLocked();
+ IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null) {
curMethod.removeStylusHandwritingWindow();
}
@@ -3123,7 +3056,7 @@
try {
// Set a subtype to this input method.
// subtypeId the name of a subtype which will be set.
- setSelectedInputMethodAndSubtypeLocked(info, subtypeId, false);
+ setSelectedInputMethodAndSubtypeLocked(info, subtypeId, false, userId);
// mCurMethodId should be updated after setSelectedInputMethodAndSubtypeLocked()
// because mCurMethodId is stored as a history in
// setSelectedInputMethodAndSubtypeLocked().
@@ -3135,7 +3068,7 @@
intent.putExtra("input_method_id", id);
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
}
- unbindCurrentClientLocked(UnbindReason.SWITCH_IME);
+ unbindCurrentClientLocked(UnbindReason.SWITCH_IME, userId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3147,24 +3080,30 @@
int lastClickToolType, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput");
- int uid = Binder.getCallingUid();
+ final int uid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(uid);
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#showSoftInput", mDumper);
synchronized (ImfLock.class) {
- if (!canInteractWithImeLocked(uid, client, "showSoftInput", statsToken)) {
+ final int userId = resolveImeUserIdLocked(callingUserId);
+ if (!canInteractWithImeLocked(uid, client, "showSoftInput", statsToken,
+ userId)) {
ImeTracker.forLogging().onFailed(
statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return false;
}
final long ident = Binder.clearCallingIdentity();
+ final var userData = getUserData(userId);
try {
if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
if (Flags.refactorInsetsController()) {
boolean wasVisible = isInputShownLocked();
- if (mImeBindingState != null && mImeBindingState.mFocusedWindowClient != null
- && mImeBindingState.mFocusedWindowClient.mClient != null) {
- mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(true);
+ if (userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindowClient != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+ userData.mImeBindingState.mFocusedWindowClient.mClient
+ .setImeVisibility(true);
if (resultReceiver != null) {
resultReceiver.send(
wasVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN
@@ -3175,7 +3114,7 @@
return false;
} else {
return showCurrentInputLocked(windowToken, statsToken, flags, lastClickToolType,
- resultReceiver, reason);
+ resultReceiver, reason, userId);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -3189,12 +3128,14 @@
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#showSoftInput", mDumper);
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Infer userId from windowToken
+ final int userId = mCurrentUserId;
final long ident = Binder.clearCallingIdentity();
try {
if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
return showCurrentInputLocked(windowToken, null /* statsToken */, 0 /* flags */,
0 /* lastClickTooType */, null /* resultReceiver */,
- SoftInputShowHideReason.SHOW_SOFT_INPUT);
+ SoftInputShowHideReason.SHOW_SOFT_INPUT, userId);
} finally {
Binder.restoreCallingIdentity(ident);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -3207,11 +3148,14 @@
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#hideSoftInput", mDumper);
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Infer userId from windowToken
+ final int userId = mCurrentUserId;
final long ident = Binder.clearCallingIdentity();
try {
if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
return hideCurrentInputLocked(windowToken, null /* statsToken */, 0 /* flags */,
- null /* resultReceiver */, SoftInputShowHideReason.HIDE_SOFT_INPUT);
+ null /* resultReceiver */, SoftInputShowHideReason.HIDE_SOFT_INPUT,
+ userId);
} finally {
Binder.restoreCallingIdentity(ident);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -3300,13 +3244,15 @@
try {
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#startStylusHandwriting", mDumper);
- int uid = Binder.getCallingUid();
+ final int uid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(uid);
synchronized (ImfLock.class) {
+ final int userId = resolveImeUserIdLocked(callingUserId);
if (!acceptingDelegation) {
mHwController.clearPendingHandwritingDelegation();
}
if (!canInteractWithImeLocked(uid, client, "startStylusHandwriting",
- null /* statsToken */)) {
+ null /* statsToken */, userId)) {
return false;
}
if (!hasSupportedStylusLocked()) {
@@ -3316,7 +3262,7 @@
}
final long ident = Binder.clearCallingIdentity();
try {
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ final var bindingController = getInputMethodBindingController(userId);
if (!bindingController.supportsStylusHandwriting()) {
Slog.w(TAG,
"Stylus HW unsupported by IME. Ignoring startStylusHandwriting()");
@@ -3341,7 +3287,7 @@
return false;
}
if (DEBUG) Slog.v(TAG, "Client requesting Stylus Handwriting to be started");
- final IInputMethodInvoker curMethod = getCurMethodLocked();
+ final IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod != null) {
curMethod.canStartStylusHandwriting(requestId.getAsInt(),
connectionlessCallback, cursorAnchorInfo,
@@ -3413,8 +3359,9 @@
return false;
}
synchronized (ImfLock.class) {
+ final var bindingController = getInputMethodBindingController(userId);
if (mHwController.isDelegationUsingConnectionlessFlow()) {
- final IInputMethodInvoker curMethod = getCurMethodLocked();
+ final IInputMethodInvoker curMethod = bindingController.getCurMethod();
if (curMethod == null) {
return false;
}
@@ -3464,29 +3411,32 @@
Objects.requireNonNull(windowToken, "windowToken must not be null");
synchronized (ImfLock.class) {
Boolean windowPerceptible = mFocusedWindowPerceptible.get(windowToken);
- if (mImeBindingState.mFocusedWindow != windowToken
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
+ if (userData.mImeBindingState.mFocusedWindow != windowToken
|| (windowPerceptible != null && windowPerceptible == perceptible)) {
return;
}
mFocusedWindowPerceptible.put(windowToken, windowPerceptible);
- updateSystemUiLocked();
+ updateSystemUiLocked(mCurrentUserId);
}
});
}
@GuardedBy("ImfLock.class")
private boolean showCurrentInputLocked(IBinder windowToken,
- @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason) {
- final var statsToken = createStatsTokenForFocusedClient(true /* show */, reason);
+ @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason,
+ @UserIdInt int userId) {
+ final var statsToken = createStatsTokenForFocusedClient(true /* show */, reason, userId);
return showCurrentInputLocked(windowToken, statsToken, flags,
- MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason);
+ MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason, userId);
}
@GuardedBy("ImfLock.class")
boolean showCurrentInputLocked(IBinder windowToken,
@NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
@MotionEvent.ToolType int lastClickToolType, @Nullable ResultReceiver resultReceiver,
- @SoftInputShowHideReason int reason) {
+ @SoftInputShowHideReason int reason, @UserIdInt int userId) {
if (!mVisibilityStateComputer.onImeShowFlags(statsToken, flags)) {
return false;
}
@@ -3499,22 +3449,24 @@
mVisibilityStateComputer.requestImeVisibility(windowToken, true);
- final int userId = mCurrentUserId;
// Ensure binding the connection when IME is going to show.
final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
bindingController.setCurrentMethodVisible();
final IInputMethodInvoker curMethod = bindingController.getCurMethod();
- ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+ ImeTracker.forLogging().onCancelled(userData.mCurStatsToken,
+ ImeTracker.PHASE_SERVER_WAIT_IME);
final boolean readyToDispatchToIme;
if (Flags.deferShowSoftInputUntilSessionCreation()) {
readyToDispatchToIme =
- curMethod != null && mCurClient != null && mCurClient.mCurSession != null;
+ curMethod != null && userData.mCurClient != null
+ && userData.mCurClient.mCurSession != null;
} else {
readyToDispatchToIme = curMethod != null;
}
if (readyToDispatchToIme) {
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_HAS_IME);
- mCurStatsToken = null;
+ userData.mCurStatsToken = null;
if (Flags.useHandwritingListenerForTooltype()) {
maybeReportToolType();
@@ -3528,7 +3480,7 @@
return true;
} else {
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
- mCurStatsToken = statsToken;
+ userData.mCurStatsToken = statsToken;
}
return false;
}
@@ -3560,11 +3512,13 @@
public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken,
@NonNull ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags,
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
- int uid = Binder.getCallingUid();
+ final int uid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(uid);
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#hideSoftInput", mDumper);
synchronized (ImfLock.class) {
- if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken)) {
+ final int userId = resolveImeUserIdLocked(callingUserId);
+ if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken, userId)) {
if (isInputShownLocked()) {
ImeTracker.forLogging().onFailed(
statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
@@ -3575,15 +3529,18 @@
return false;
}
final long ident = Binder.clearCallingIdentity();
+ final var userData = getUserData(userId);
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput");
if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
if (Flags.refactorInsetsController()) {
- if (mImeBindingState != null && mImeBindingState.mFocusedWindowClient != null
- && mImeBindingState.mFocusedWindowClient.mClient != null) {
+ if (userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindowClient != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
boolean wasVisible = isInputShownLocked();
// TODO add windowToken to interface
- mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(false);
+ userData.mImeBindingState.mFocusedWindowClient.mClient
+ .setImeVisibility(false);
if (resultReceiver != null) {
resultReceiver.send(wasVisible ? InputMethodManager.RESULT_HIDDEN
: InputMethodManager.RESULT_UNCHANGED_HIDDEN, null);
@@ -3593,7 +3550,7 @@
return false;
} else {
return InputMethodManagerService.this.hideCurrentInputLocked(windowToken,
- statsToken, flags, resultReceiver, reason);
+ statsToken, flags, resultReceiver, reason, userId);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -3605,47 +3562,52 @@
@Override
@IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
public void hideSoftInputFromServerForTest() {
+ final int callingUserId = UserHandle.getCallingUserId();
synchronized (ImfLock.class) {
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- SoftInputShowHideReason.HIDE_SOFT_INPUT);
+ final int userId = resolveImeUserIdLocked(callingUserId);
+ final var userData = getUserData(userId);
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+ SoftInputShowHideReason.HIDE_SOFT_INPUT, userId);
}
}
@GuardedBy("ImfLock.class")
private boolean hideCurrentInputLocked(IBinder windowToken,
- @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason) {
- final var statsToken = createStatsTokenForFocusedClient(false /* show */, reason);
+ @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason,
+ @UserIdInt int userId) {
+ final var statsToken = createStatsTokenForFocusedClient(false /* show */, reason, userId);
return hideCurrentInputLocked(windowToken, statsToken, flags, null /* resultReceiver */,
- reason);
+ reason, userId);
}
@GuardedBy("ImfLock.class")
boolean hideCurrentInputLocked(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
@InputMethodManager.HideFlags int flags, @Nullable ResultReceiver resultReceiver,
- @SoftInputShowHideReason int reason) {
+ @SoftInputShowHideReason int reason, @UserIdInt int userId) {
+ final var bindingController = getInputMethodBindingController(userId);
if (!mVisibilityStateComputer.canHideIme(statsToken, flags)) {
return false;
}
// There is a chance that IMM#hideSoftInput() is called in a transient state where
- // IMMS#InputShown is already updated to be true whereas IMMS#mImeWindowVis is still waiting
- // to be updated with the new value sent from IME process. Even in such a transient state
- // historically we have accepted an incoming call of IMM#hideSoftInput() from the
+ // IMMS#InputShown is already updated to be true whereas the user's ImeWindowVis is still
+ // waiting to be updated with the new value sent from IME process. Even in such a transient
+ // state historically we have accepted an incoming call of IMM#hideSoftInput() from the
// application process as a valid request, and have even promised such a behavior with CTS
// since Android Eclair. That's why we need to accept IMM#hideSoftInput() even when only
// IMMS#InputShown indicates that the software keyboard is shown.
// TODO(b/246309664): Clean up IMMS#mImeWindowVis
- final int userId = mCurrentUserId;
- final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
IInputMethodInvoker curMethod = bindingController.getCurMethod();
final boolean shouldHideSoftInput = curMethod != null
- && (isInputShownLocked() || (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0);
+ && (isInputShownLocked()
+ || (bindingController.getImeWindowVis() & InputMethodService.IME_ACTIVE) != 0);
mVisibilityStateComputer.requestImeVisibility(windowToken, false);
if (shouldHideSoftInput) {
// The IME will report its visible state again after the following message finally
// delivered to the IME process as an IPC. Hence the inconsistency between
- // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
+ // IMMS#mInputShown and the user's ImeWindowVis should be resolved spontaneously in
// the final state.
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason,
@@ -3656,8 +3618,9 @@
bindingController.setCurrentMethodNotVisible();
mVisibilityStateComputer.clearImeShowFlags();
// Cancel existing statsToken for show IME as we got a hide request.
- ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
- mCurStatsToken = null;
+ ImeTracker.forLogging().onCancelled(userData.mCurStatsToken,
+ ImeTracker.PHASE_SERVER_WAIT_IME);
+ userData.mCurStatsToken = null;
return shouldHideSoftInput;
}
@@ -3727,7 +3690,7 @@
return new InputBindResult(
InputBindResult.ResultCode.ERROR_SYSTEM_NOT_READY,
null /* method */, null /* accessibilitySessions */, null /* channel */,
- getSelectedMethodIdLocked(),
+ bindingController.getSelectedMethodId(),
bindingController.getSequenceNumber(),
false /* isInputMethodSuppressingSpellChecker */);
}
@@ -3787,7 +3750,8 @@
final boolean shouldClearFlag =
mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.mUid);
final boolean showForced = mVisibilityStateComputer.mShowForced;
- if (mImeBindingState.mFocusedWindow != windowToken
+ final var userData = getUserData(userId);
+ if (userData.mImeBindingState.mFocusedWindow != windowToken
&& showForced && shouldClearFlag) {
mVisibilityStateComputer.mShowForced = false;
}
@@ -3806,8 +3770,8 @@
Slog.w(TAG, "If you need to impersonate a foreground user/profile from"
+ " a background user, use EditorInfo.targetInputMethodUser with"
+ " INTERACT_ACROSS_USERS_FULL permission.");
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- SoftInputShowHideReason.HIDE_INVALID_USER);
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ 0 /* flags */, SoftInputShowHideReason.HIDE_INVALID_USER, userId);
return InputBindResult.INVALID_USER;
}
@@ -3867,7 +3831,9 @@
+ " cs=" + cs);
}
- final boolean sameWindowFocused = mImeBindingState.mFocusedWindow == windowToken;
+ final int userId = bindingController.getUserId();
+ final var userData = getUserData(userId);
+ final boolean sameWindowFocused = userData.mImeBindingState.mFocusedWindow == windowToken;
final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0;
final boolean startInputByWinGainedFocus =
(startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) != 0;
@@ -3899,7 +3865,7 @@
null, null, null, null, -1, false);
}
- mImeBindingState = new ImeBindingState(bindingController.mUserId, windowToken,
+ userData.mImeBindingState = new ImeBindingState(bindingController.getUserId(), windowToken,
softInputMode, cs, editorInfo);
mFocusedWindowPerceptible.put(windowToken, true);
@@ -3930,16 +3896,17 @@
}
break;
}
- final var statsToken = createStatsTokenForFocusedClient(isShow, imeVisRes.getReason());
- mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
- imeVisRes.getState(), imeVisRes.getReason());
+ final var statsToken = createStatsTokenForFocusedClient(isShow, imeVisRes.getReason(),
+ userId);
+ mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
+ statsToken, imeVisRes.getState(), imeVisRes.getReason(), userId);
if (imeVisRes.getReason() == SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW) {
// If focused display changed, we should unbind current method
// to make app window in previous display relayout after Ime
// window token removed.
// Note that we can trust client's display ID as long as it matches
// to the display ID obtained from the window.
- if (cs.mSelfReportedDisplayId != getCurTokenDisplayIdLocked()) {
+ if (cs.mSelfReportedDisplayId != bindingController.getCurTokenDisplayId()) {
bindingController.unbindCurrentMethod();
}
}
@@ -3959,9 +3926,10 @@
@GuardedBy("ImfLock.class")
private boolean canInteractWithImeLocked(int uid, IInputMethodClient client, String methodName,
- @Nullable ImeTracker.Token statsToken) {
- if (mCurClient == null || client == null
- || mCurClient.mClient.asBinder() != client.asBinder()) {
+ @Nullable ImeTracker.Token statsToken, @UserIdInt int userId) {
+ final var userData = getUserData(userId);
+ if (userData.mCurClient == null || client == null
+ || userData.mCurClient.mClient.asBinder() != client.asBinder()) {
// We need to check if this is the current client with
// focus in the window manager, to allow this call to
// be made before input is started in it.
@@ -3971,7 +3939,7 @@
throw new IllegalArgumentException("unknown client " + client.asBinder());
}
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
- if (!isImeClientFocused(mImeBindingState.mFocusedWindow, cs)) {
+ if (!isImeClientFocused(userData.mImeBindingState.mFocusedWindow, cs)) {
Slog.w(TAG, String.format("Ignoring %s of uid %d : %s", methodName, uid, client));
return false;
}
@@ -3983,14 +3951,18 @@
@GuardedBy("ImfLock.class")
private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
final int uid = Binder.getCallingUid();
- if (mImeBindingState.mFocusedWindowClient != null && client != null
- && mImeBindingState.mFocusedWindowClient.mClient.asBinder() == client.asBinder()) {
+ // TODO(b/305849394): Get userId from callers.
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
+ if (userData.mImeBindingState.mFocusedWindowClient != null && client != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient.asBinder()
+ == client.asBinder()) {
return true;
}
- if (mCurrentUserId != UserHandle.getUserId(uid)) {
+ if (userId != UserHandle.getUserId(uid)) {
return false;
}
- final var curIntent = getInputMethodBindingController(mCurrentUserId).getCurIntent();
+ final var curIntent = getInputMethodBindingController(userId).getCurIntent();
if (curIntent != null && InputMethodUtils.checkIfPackageBelongsToUid(
mPackageManagerInternal, uid, curIntent.getComponent().getPackageName())) {
return true;
@@ -4001,17 +3973,19 @@
@Override
public void showInputMethodPickerFromClient(IInputMethodClient client,
int auxiliarySubtypeMode) {
+ final int callingUserId = UserHandle.getCallingUserId();
synchronized (ImfLock.class) {
if (!canShowInputMethodPickerLocked(client)) {
Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
+ Binder.getCallingUid() + ": " + client);
return;
}
-
+ final int userId = resolveImeUserIdLocked(callingUserId);
+ final var userData = getUserData(userId);
// Always call subtype picker, because subtype picker is a superset of input method
// picker.
- final int displayId =
- (mCurClient != null) ? mCurClient.mSelfReportedDisplayId : DEFAULT_DISPLAY;
+ final int displayId = (userData.mCurClient != null)
+ ? userData.mCurClient.mSelfReportedDisplayId : DEFAULT_DISPLAY;
mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId)
.sendToTarget();
}
@@ -4043,33 +4017,31 @@
}
@BinderThread
- private void setInputMethod(@NonNull IBinder token, String id) {
+ private void setInputMethod(@NonNull IBinder token, String id, @UserIdInt int userId) {
final int callingUid = Binder.getCallingUid();
- final int userId = UserHandle.getUserId(callingUid);
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return;
}
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final InputMethodInfo imi = settings.getMethodMap().get(id);
if (imi == null || !canCallerAccessInputMethod(
imi.getPackageName(), callingUid, userId, settings)) {
throw getExceptionForUnknownImeId(id);
}
- setInputMethodWithSubtypeIdLocked(token, id, NOT_A_SUBTYPE_ID);
+ setInputMethodWithSubtypeIdLocked(token, id, NOT_A_SUBTYPE_ID, userId);
}
}
@BinderThread
private void setInputMethodAndSubtype(@NonNull IBinder token, String id,
- InputMethodSubtype subtype) {
+ InputMethodSubtype subtype, @UserIdInt int userId) {
final int callingUid = Binder.getCallingUid();
- final int userId = UserHandle.getUserId(callingUid);
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return;
}
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final InputMethodInfo imi = settings.getMethodMap().get(id);
if (imi == null || !canCallerAccessInputMethod(
imi.getPackageName(), callingUid, userId, settings)) {
@@ -4077,20 +4049,19 @@
}
if (subtype != null) {
setInputMethodWithSubtypeIdLocked(token, id,
- SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()));
+ SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()), userId);
} else {
- setInputMethod(token, id);
+ setInputMethod(token, id, userId);
}
}
}
@BinderThread
- private boolean switchToPreviousInputMethod(@NonNull IBinder token) {
+ private boolean switchToPreviousInputMethod(@NonNull IBinder token, @UserIdInt int userId) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return false;
}
- final int userId = mCurrentUserId;
final var bindingController = getInputMethodBindingController(userId);
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final Pair<String, String> lastIme = settings.getLastInputMethodAndSubtype();
@@ -4155,9 +4126,10 @@
if (!TextUtils.isEmpty(targetLastImiId)) {
if (DEBUG) {
Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second
- + ", from: " + getSelectedMethodIdLocked() + ", " + subtypeId);
+ + ", from: " + bindingController.getSelectedMethodId() + ", "
+ + subtypeId);
}
- setInputMethodWithSubtypeIdLocked(token, targetLastImiId, subtypeId);
+ setInputMethodWithSubtypeIdLocked(token, targetLastImiId, subtypeId, userId);
return true;
} else {
return false;
@@ -4166,18 +4138,19 @@
}
@BinderThread
- private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme) {
+ private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme,
+ @UserIdInt int userId) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return false;
}
- return switchToNextInputMethodLocked(token, onlyCurrentIme);
+ return switchToNextInputMethodLocked(token, onlyCurrentIme, userId);
}
}
@GuardedBy("ImfLock.class")
- private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme) {
- final int userId = mCurrentUserId;
+ private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme,
+ @UserIdInt int userId) {
final var bindingController = getInputMethodBindingController(userId);
final var currentImi = bindingController.getSelectedMethod();
final ImeSubtypeListItem nextSubtype = getUserData(userId).mSwitchingController
@@ -4187,17 +4160,17 @@
return false;
}
setInputMethodWithSubtypeIdLocked(token, nextSubtype.mImi.getId(),
- nextSubtype.mSubtypeId);
+ nextSubtype.mSubtypeId, userId);
return true;
}
@BinderThread
- private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token) {
+ private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token,
+ @UserIdInt int userId) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return false;
}
- final int userId = mCurrentUserId;
final var bindingController = getInputMethodBindingController(userId);
final var currentImi = bindingController.getSelectedMethod();
final ImeSubtypeListItem nextSubtype = getUserData(userId).mSwitchingController
@@ -4259,7 +4232,8 @@
DirectBootAwareness.AUTO);
InputMethodSettingsRepository.put(userId, newSettings);
if (isCurrentUser) {
- postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
+ postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */,
+ userId);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -4298,7 +4272,7 @@
if (mSettingsObserver != null) {
mSettingsObserver.mLastEnabled = settings.getEnabledInputMethodsStr();
}
- updateInputMethodsFromSettingsLocked(false /* enabledChanged */);
+ updateInputMethodsFromSettingsLocked(false /* enabledChanged */, userId);
}
}
} finally {
@@ -4317,17 +4291,20 @@
@Override
@Deprecated
public int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) {
- int callingUid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getCallingUserId();
return Binder.withCleanCallingIdentity(() -> {
final int curTokenDisplayId;
synchronized (ImfLock.class) {
+ final int userId = resolveImeUserIdLocked(callingUserId);
if (!canInteractWithImeLocked(callingUid, client,
- "getInputMethodWindowVisibleHeight", null /* statsToken */)) {
+ "getInputMethodWindowVisibleHeight", null /* statsToken */, userId)) {
return 0;
}
+ final var bindingController = getInputMethodBindingController(userId);
// This should probably use the caller's display id, but because this is unsupported
// and maintained only for compatibility, there's no point in fixing it.
- curTokenDisplayId = getCurTokenDisplayIdLocked();
+ curTokenDisplayId = bindingController.getCurTokenDisplayId();
}
return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId);
});
@@ -4452,10 +4429,12 @@
@IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
@Override
public void addVirtualStylusIdForTestSession(IInputMethodClient client) {
- int uid = Binder.getCallingUid();
+ final int uid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(uid);
synchronized (ImfLock.class) {
+ final int userId = resolveImeUserIdLocked(callingUserId);
if (!canInteractWithImeLocked(uid, client, "addVirtualStylusIdForTestSession",
- null /* statsToken */)) {
+ null /* statsToken */, userId)) {
return;
}
final long ident = Binder.clearCallingIdentity();
@@ -4479,10 +4458,12 @@
@Override
public void setStylusWindowIdleTimeoutForTest(
IInputMethodClient client, @DurationMillisLong long timeout) {
- int uid = Binder.getCallingUid();
+ final int uid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(uid);
synchronized (ImfLock.class) {
+ final int userId = resolveImeUserIdLocked(callingUserId);
if (!canInteractWithImeLocked(uid, client, "setStylusWindowIdleTimeoutForTest",
- null /* statsToken */)) {
+ null /* statsToken */, userId)) {
return;
}
final long ident = Binder.clearCallingIdentity();
@@ -4592,50 +4573,51 @@
private void dumpDebug(ProtoOutputStream proto, long fieldId) {
synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ final int userId = mCurrentUserId;
+ final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
final long token = proto.start(fieldId);
- proto.write(CUR_METHOD_ID, getSelectedMethodIdLocked());
+ proto.write(CUR_METHOD_ID, bindingController.getSelectedMethodId());
proto.write(CUR_SEQ, bindingController.getSequenceNumber());
- proto.write(CUR_CLIENT, Objects.toString(mCurClient));
- mImeBindingState.dumpDebug(proto, mWindowManagerInternal);
+ proto.write(CUR_CLIENT, Objects.toString(userData.mCurClient));
+ userData.mImeBindingState.dumpDebug(proto, mWindowManagerInternal);
proto.write(LAST_IME_TARGET_WINDOW_NAME,
mWindowManagerInternal.getWindowName(mLastImeTargetWindow));
proto.write(CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE, InputMethodDebug.softInputModeToString(
- mImeBindingState.mFocusedWindowSoftInputMode));
- if (mCurEditorInfo != null) {
- mCurEditorInfo.dumpDebug(proto, CUR_ATTRIBUTE);
+ userData.mImeBindingState.mFocusedWindowSoftInputMode));
+ if (userData.mCurEditorInfo != null) {
+ userData.mCurEditorInfo.dumpDebug(proto, CUR_ATTRIBUTE);
}
proto.write(CUR_ID, bindingController.getCurId());
mVisibilityStateComputer.dumpDebug(proto, fieldId);
- proto.write(IN_FULLSCREEN_MODE, mInFullscreenMode);
- proto.write(CUR_TOKEN, Objects.toString(getCurTokenLocked()));
- proto.write(CUR_TOKEN_DISPLAY_ID, getCurTokenDisplayIdLocked());
+ proto.write(IN_FULLSCREEN_MODE, userData.mInFullscreenMode);
+ proto.write(CUR_TOKEN, Objects.toString(bindingController.getCurToken()));
+ proto.write(CUR_TOKEN_DISPLAY_ID, bindingController.getCurTokenDisplayId());
proto.write(SYSTEM_READY, mSystemReady);
proto.write(HAVE_CONNECTION, bindingController.hasMainConnection());
- proto.write(BOUND_TO_METHOD, mBoundToMethod);
+ proto.write(BOUND_TO_METHOD, userData.mBoundToMethod);
proto.write(IS_INTERACTIVE, mIsInteractive);
- proto.write(BACK_DISPOSITION, mBackDisposition);
- proto.write(IME_WINDOW_VISIBILITY, mImeWindowVis);
+ proto.write(BACK_DISPOSITION, bindingController.getBackDisposition());
+ proto.write(IME_WINDOW_VISIBILITY, bindingController.getImeWindowVis());
proto.write(SHOW_IME_WITH_HARD_KEYBOARD, mMenuController.getShowImeWithHardKeyboard());
proto.end(token);
}
}
@BinderThread
- private void notifyUserAction(@NonNull IBinder token) {
+ private void notifyUserAction(@NonNull IBinder token, @UserIdInt int userId) {
if (DEBUG) {
Slog.d(TAG, "Got the notification of a user action.");
}
synchronized (ImfLock.class) {
- if (getCurTokenLocked() != token) {
+ final var bindingController = getInputMethodBindingController(userId);
+ if (bindingController.getCurToken() != token) {
if (DEBUG) {
Slog.d(TAG, "Ignoring the user action notification from IMEs that are no longer"
+ " active.");
}
return;
}
- final int userId = mCurrentUserId;
- final var bindingController = getInputMethodBindingController(userId);
final InputMethodInfo imi = bindingController.getSelectedMethod();
if (imi != null) {
getUserData(userId).mSwitchingController.onUserActionLocked(imi,
@@ -4646,11 +4628,11 @@
@BinderThread
private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible,
- @NonNull ImeTracker.Token statsToken) {
+ @NonNull ImeTracker.Token statsToken, @UserIdInt int userId) {
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
return;
@@ -4658,10 +4640,11 @@
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(
- windowToken);
+ windowToken, userId);
mVisibilityApplier.applyImeVisibility(requestToken, statsToken,
setVisible ? ImeVisibilityStateComputer.STATE_SHOW_IME
- : ImeVisibilityStateComputer.STATE_HIDE_IME, mCurrentUserId);
+ : ImeVisibilityStateComputer.STATE_HIDE_IME,
+ SoftInputShowHideReason.NOT_SET /* ignore reason */, userId);
}
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -4682,7 +4665,9 @@
}
@GuardedBy("ImfLock.class")
- private void setInputMethodWithSubtypeIdLocked(IBinder token, String id, int subtypeId) {
+ private void setInputMethodWithSubtypeIdLocked(IBinder token, String id, int subtypeId,
+ @UserIdInt int userId) {
+ final var bindingController = getInputMethodBindingController(userId);
if (token == null) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_SECURE_SETTINGS)
@@ -4691,13 +4676,13 @@
"Using null token requires permission "
+ android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
- } else if (getCurTokenLocked() != token) {
+ } else if (bindingController.getCurToken() != token) {
Slog.w(TAG, "Ignoring setInputMethod of uid " + Binder.getCallingUid()
+ " token: " + token);
return;
} else {
// Called with current IME's token.
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (settings.getMethodMap().get(id) != null
&& settings.getEnabledInputMethodListWithFilter(
(info) -> info.getId().equals(id)).isEmpty()) {
@@ -4707,7 +4692,7 @@
final long ident = Binder.clearCallingIdentity();
try {
- setInputMethodLocked(id, subtypeId);
+ setInputMethodLocked(id, subtypeId, userId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4720,17 +4705,20 @@
void onShowHideSoftInputRequested(boolean show, IBinder requestImeToken,
@SoftInputShowHideReason int reason, @Nullable ImeTracker.Token statsToken,
@UserIdInt int userId) {
- final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken);
+ final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken,
+ userId);
final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
final WindowManagerInternal.ImeTargetInfo info =
mWindowManagerInternal.onToggleImeRequested(
- show, mImeBindingState.mFocusedWindow, requestToken,
+ show, userData.mImeBindingState.mFocusedWindow, requestToken,
bindingController.getCurTokenDisplayId());
mSoftInputShowHideHistory.addEntry(new SoftInputShowHideHistory.Entry(
- mImeBindingState.mFocusedWindowClient, mImeBindingState.mFocusedWindowEditorInfo,
- info.focusedWindowName, mImeBindingState.mFocusedWindowSoftInputMode, reason,
- mInFullscreenMode, info.requestWindowName, info.imeControlTargetName,
- info.imeLayerTargetName, info.imeSurfaceParentName));
+ userData.mImeBindingState.mFocusedWindowClient,
+ userData.mImeBindingState.mFocusedWindowEditorInfo,
+ info.focusedWindowName, userData.mImeBindingState.mFocusedWindowSoftInputMode,
+ reason, userData.mInFullscreenMode, info.requestWindowName,
+ info.imeControlTargetName, info.imeLayerTargetName, info.imeSurfaceParentName));
if (statsToken != null) {
mImeTrackerService.onImmsUpdate(statsToken, info.requestWindowName);
@@ -4739,30 +4727,33 @@
@BinderThread
private void hideMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken,
- @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason) {
+ @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason,
+ @UserIdInt int userId) {
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput");
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
return;
}
+ final var userData = getUserData(userId);
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
final long ident = Binder.clearCallingIdentity();
try {
if (Flags.refactorInsetsController()) {
- mCurClient.mClient.setImeVisibility(false);
+ userData.mCurClient.mClient.setImeVisibility(false);
// TODO we will loose the flags here
- if (mImeBindingState != null
- && mImeBindingState.mFocusedWindowClient != null
- && mImeBindingState.mFocusedWindowClient.mClient != null) {
- mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(false);
+ if (userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindowClient != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+ userData.mImeBindingState.mFocusedWindowClient.mClient
+ .setImeVisibility(false);
}
} else {
hideCurrentInputLocked(mLastImeTargetWindow, statsToken, flags,
- null /* resultReceiver */, reason);
+ null /* resultReceiver */, reason, userId);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -4775,30 +4766,34 @@
@BinderThread
private void showMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken,
- @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason) {
+ @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason,
+ @UserIdInt int userId) {
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput");
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
return;
}
+ final var userData = getUserData(userId);
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
final long ident = Binder.clearCallingIdentity();
try {
if (Flags.refactorInsetsController()) {
- mCurClient.mClient.setImeVisibility(false);
+ userData.mCurClient.mClient.setImeVisibility(false);
// TODO we will loose the flags here
- if (mImeBindingState != null
- && mImeBindingState.mFocusedWindowClient != null
- && mImeBindingState.mFocusedWindowClient.mClient != null) {
- mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(true);
+ if (userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindowClient != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+ userData.mImeBindingState.mFocusedWindowClient.mClient
+ .setImeVisibility(true);
}
} else {
showCurrentInputLocked(mLastImeTargetWindow, statsToken, flags,
- MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason);
+ MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason,
+ userId);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -4809,46 +4804,52 @@
}
}
+ @GuardedBy("ImfLock.class")
@VisibleForTesting
- ImeVisibilityApplier getVisibilityApplier() {
- synchronized (ImfLock.class) {
- return mVisibilityApplier;
- }
+ DefaultImeVisibilityApplier getVisibilityApplierLocked() {
+ return mVisibilityApplier;
}
void onApplyImeVisibilityFromComputer(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
@NonNull ImeVisibilityResult result) {
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Infer userId from windowToken
+ final int userId = mCurrentUserId;
mVisibilityApplier.applyImeVisibility(windowToken, statsToken, result.getState(),
- result.getReason());
+ result.getReason(), userId);
}
}
@GuardedBy("ImfLock.class")
- void setEnabledSessionLocked(SessionState session) {
- if (mEnabledSession != session) {
- if (mEnabledSession != null && mEnabledSession.mSession != null) {
- if (DEBUG) Slog.v(TAG, "Disabling: " + mEnabledSession);
- mEnabledSession.mMethod.setSessionEnabled(mEnabledSession.mSession, false);
+ void setEnabledSessionLocked(SessionState session,
+ @NonNull UserDataRepository.UserData userData) {
+ if (userData.mEnabledSession != session) {
+ if (userData.mEnabledSession != null && userData.mEnabledSession.mSession != null) {
+ if (DEBUG) Slog.v(TAG, "Disabling: " + userData.mEnabledSession);
+ userData.mEnabledSession.mMethod.setSessionEnabled(
+ userData.mEnabledSession.mSession, false);
}
- mEnabledSession = session;
- if (mEnabledSession != null && mEnabledSession.mSession != null) {
- if (DEBUG) Slog.v(TAG, "Enabling: " + mEnabledSession);
- mEnabledSession.mMethod.setSessionEnabled(mEnabledSession.mSession, true);
+ userData.mEnabledSession = session;
+ if (userData.mEnabledSession != null && userData.mEnabledSession.mSession != null) {
+ if (DEBUG) Slog.v(TAG, "Enabling: " + userData.mEnabledSession);
+ userData.mEnabledSession.mMethod.setSessionEnabled(
+ userData.mEnabledSession.mSession, true);
}
}
}
@GuardedBy("ImfLock.class")
void setEnabledSessionForAccessibilityLocked(
- SparseArray<AccessibilitySessionState> accessibilitySessions) {
+ SparseArray<AccessibilitySessionState> accessibilitySessions,
+ @NonNull UserDataRepository.UserData userData) {
// mEnabledAccessibilitySessions could the same object as accessibilitySessions.
SparseArray<IAccessibilityInputMethodSession> disabledSessions = new SparseArray<>();
- for (int i = 0; i < mEnabledAccessibilitySessions.size(); i++) {
- if (!accessibilitySessions.contains(mEnabledAccessibilitySessions.keyAt(i))) {
- AccessibilitySessionState sessionState = mEnabledAccessibilitySessions.valueAt(i);
+ for (int i = 0; i < userData.mEnabledAccessibilitySessions.size(); i++) {
+ if (!accessibilitySessions.contains(userData.mEnabledAccessibilitySessions.keyAt(i))) {
+ AccessibilitySessionState sessionState =
+ userData.mEnabledAccessibilitySessions.valueAt(i);
if (sessionState != null) {
- disabledSessions.append(mEnabledAccessibilitySessions.keyAt(i),
+ disabledSessions.append(userData.mEnabledAccessibilitySessions.keyAt(i),
sessionState.mSession);
}
}
@@ -4859,7 +4860,7 @@
}
SparseArray<IAccessibilityInputMethodSession> enabledSessions = new SparseArray<>();
for (int i = 0; i < accessibilitySessions.size(); i++) {
- if (!mEnabledAccessibilitySessions.contains(accessibilitySessions.keyAt(i))) {
+ if (!userData.mEnabledAccessibilitySessions.contains(accessibilitySessions.keyAt(i))) {
AccessibilitySessionState sessionState = accessibilitySessions.valueAt(i);
if (sessionState != null) {
enabledSessions.append(accessibilitySessions.keyAt(i), sessionState.mSession);
@@ -4870,7 +4871,7 @@
AccessibilityManagerInternal.get().setImeSessionEnabled(enabledSessions,
true);
}
- mEnabledAccessibilitySessions = accessibilitySessions;
+ userData.mEnabledAccessibilitySessions = accessibilitySessions;
}
@SuppressWarnings("unchecked")
@@ -4930,25 +4931,33 @@
case MSG_HIDE_ALL_INPUT_METHODS:
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Needs to figure out what to do where for background users.
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
if (Flags.refactorInsetsController()) {
- if (mImeBindingState != null
- && mImeBindingState.mFocusedWindowClient != null
- && mImeBindingState.mFocusedWindowClient.mClient != null) {
- mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(false);
+ if (userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindowClient != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+ userData.mImeBindingState.mFocusedWindowClient.mClient
+ .setImeVisibility(false);
}
} else {
@SoftInputShowHideReason final int reason = (int) msg.obj;
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- reason);
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ 0 /* flags */, reason, userId);
}
}
return true;
case MSG_REMOVE_IME_SURFACE: {
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Needs to figure out what to do where for background users.
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
try {
- if (mEnabledSession != null && mEnabledSession.mSession != null
- && !isShowRequestedForCurrentWindow()) {
- mEnabledSession.mSession.removeImeSurface();
+ if (userData.mEnabledSession != null
+ && userData.mEnabledSession.mSession != null
+ && !isShowRequestedForCurrentWindow(userId)) {
+ userData.mEnabledSession.mSession.removeImeSurface();
}
} catch (RemoteException e) {
}
@@ -4958,10 +4967,14 @@
case MSG_REMOVE_IME_SURFACE_FROM_WINDOW: {
IBinder windowToken = (IBinder) msg.obj;
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Infer userId from windowToken.
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
try {
- if (windowToken == mImeBindingState.mFocusedWindow
- && mEnabledSession != null && mEnabledSession.mSession != null) {
- mEnabledSession.mSession.removeImeSurface();
+ if (windowToken == userData.mImeBindingState.mFocusedWindow
+ && userData.mEnabledSession != null
+ && userData.mEnabledSession.mSession != null) {
+ userData.mEnabledSession.mSession.removeImeSurface();
}
} catch (RemoteException e) {
}
@@ -5014,9 +5027,11 @@
synchronized (ImfLock.class) {
final var bindingController = getInputMethodBindingController(mCurrentUserId);
if (bindingController.supportsStylusHandwriting()
- && getCurMethodLocked() != null && hasSupportedStylusLocked()) {
+ && bindingController.getCurMethod() != null
+ && hasSupportedStylusLocked()) {
Slog.d(TAG, "Initializing Handwriting Spy");
- mHwController.initializeHandwritingSpy(getCurTokenDisplayIdLocked());
+ mHwController.initializeHandwritingSpy(
+ bindingController.getCurTokenDisplayId());
} else {
mHwController.reset();
}
@@ -5033,18 +5048,21 @@
}
return true;
case MSG_START_HANDWRITING:
+ final var handwritingRequest = (HandwritingRequest) msg.obj;
synchronized (ImfLock.class) {
- IInputMethodInvoker curMethod = getCurMethodLocked();
- if (curMethod == null || mImeBindingState.mFocusedWindow == null) {
+ final int userId = handwritingRequest.userId;
+ final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
+ IInputMethodInvoker curMethod = bindingController.getCurMethod();
+ if (curMethod == null || userData.mImeBindingState.mFocusedWindow == null) {
return true;
}
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
final HandwritingModeController.HandwritingSession session =
mHwController.startHandwritingSession(
- msg.arg1 /*requestId*/,
- msg.arg2 /*pid*/,
+ handwritingRequest.requestId,
+ handwritingRequest.pid,
bindingController.getCurMethodUid(),
- mImeBindingState.mFocusedWindow);
+ userData.mImeBindingState.mFocusedWindow);
if (session == null) {
Slog.e(TAG,
"Failed to start handwriting session for requestId: " + msg.arg1);
@@ -5079,52 +5097,60 @@
return false;
}
+ private record HandwritingRequest(int requestId, int pid, @UserIdInt int userId) { }
+
@BinderThread
- private void onStylusHandwritingReady(int requestId, int pid) {
- mHandler.obtainMessage(MSG_START_HANDWRITING, requestId, pid).sendToTarget();
+ private void onStylusHandwritingReady(int requestId, int pid, @UserIdInt int userId) {
+ mHandler.obtainMessage(MSG_START_HANDWRITING,
+ new HandwritingRequest(requestId, pid, userId)).sendToTarget();
}
private void handleSetInteractive(final boolean interactive) {
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Support multiple IMEs.
+ final int userId = mCurrentUserId;
+ final var bindingController = getInputMethodBindingController(userId);
mIsInteractive = interactive;
- updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition);
-
+ updateSystemUiLocked(
+ interactive ? bindingController.getImeWindowVis() : 0,
+ bindingController.getBackDisposition(), userId);
+ final var userData = getUserData(userId);
// Inform the current client of the change in active status
- if (mCurClient == null || mCurClient.mClient == null) {
+ if (userData.mCurClient == null || userData.mCurClient.mClient == null) {
return;
}
- // TODO(b/325515685): user data must be retrieved by a userId parameter
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
if (mImePlatformCompatUtils.shouldUseSetInteractiveProtocol(
bindingController.getCurMethodUid())) {
// Handle IME visibility when interactive changed before finishing the input to
// ensure we preserve the last state as possible.
final ImeVisibilityResult imeVisRes = mVisibilityStateComputer.onInteractiveChanged(
- mImeBindingState.mFocusedWindow, interactive);
+ userData.mImeBindingState.mFocusedWindow, interactive);
if (imeVisRes != null) {
// Pass in a null statsToken as the IME snapshot is not tracked by ImeTracker.
- mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow,
- null /* statsToken */, imeVisRes.getState(), imeVisRes.getReason());
+ mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
+ null /* statsToken */, imeVisRes.getState(), imeVisRes.getReason(),
+ userId);
}
// Eligible IME processes use new "setInteractive" protocol.
- mCurClient.mClient.setInteractive(mIsInteractive, mInFullscreenMode);
+ userData.mCurClient.mClient.setInteractive(mIsInteractive,
+ userData.mInFullscreenMode);
} else {
// Legacy IME processes continue using legacy "setActive" protocol.
- mCurClient.mClient.setActive(mIsInteractive, mInFullscreenMode);
+ userData.mCurClient.mClient.setActive(mIsInteractive, userData.mInFullscreenMode);
}
}
}
@GuardedBy("ImfLock.class")
- private boolean chooseNewDefaultIMELocked() {
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ private boolean chooseNewDefaultIMELocked(@UserIdInt int userId) {
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
settings.getEnabledInputMethodList());
if (imi != null) {
if (DEBUG) {
Slog.d(TAG, "New default IME was selected: " + imi.getId());
}
- resetSelectedInputMethodAndSubtypeLocked(imi.getId());
+ resetSelectedInputMethodAndSubtypeLocked(imi.getId(), userId);
return true;
}
@@ -5227,7 +5253,8 @@
}
@GuardedBy("ImfLock.class")
- void postInputMethodSettingUpdatedLocked(boolean resetDefaultEnabledIme) {
+ void postInputMethodSettingUpdatedLocked(boolean resetDefaultEnabledIme,
+ @UserIdInt int userId) {
if (DEBUG) {
Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme
+ " \n ------ caller=" + Debug.getCallers(10));
@@ -5237,7 +5264,6 @@
return;
}
- final int userId = mCurrentUserId;
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
boolean reenableMinimumNonAuxSystemImes = false;
@@ -5262,7 +5288,7 @@
Slog.i(TAG, "All the enabled IMEs are gone. Reset default enabled IMEs.");
}
resetDefaultEnabledIme = true;
- resetSelectedInputMethodAndSubtypeLocked("");
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
} else if (!enabledNonAuxImeFound) {
if (DEBUG) {
Slog.i(TAG, "All the enabled non-Aux IMEs are gone. Do partial reset.");
@@ -5281,7 +5307,7 @@
if (DEBUG) {
Slog.d(TAG, "--- enable ime = " + imi);
}
- setInputMethodEnabledLocked(imi.getId(), true);
+ setInputMethodEnabledLocked(imi.getId(), true, userId);
}
}
@@ -5289,16 +5315,16 @@
if (!TextUtils.isEmpty(defaultImiId)) {
if (!settings.getMethodMap().containsKey(defaultImiId)) {
Slog.w(TAG, "Default IME is uninstalled. Choose new default IME.");
- if (chooseNewDefaultIMELocked()) {
- updateInputMethodsFromSettingsLocked(true);
+ if (chooseNewDefaultIMELocked(userId)) {
+ updateInputMethodsFromSettingsLocked(true, userId);
}
} else {
// Double check that the default IME is certainly enabled.
- setInputMethodEnabledLocked(defaultImiId, true);
+ setInputMethodEnabledLocked(defaultImiId, true, userId);
}
}
- updateDefaultVoiceImeIfNeededLocked();
+ updateDefaultVoiceImeIfNeededLocked(userId);
final var userData = getUserData(userId);
userData.mSwitchingController.resetCircularListLocked(mContext, settings);
@@ -5324,8 +5350,8 @@
}
@GuardedBy("ImfLock.class")
- private void updateDefaultVoiceImeIfNeededLocked() {
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ private void updateDefaultVoiceImeIfNeededLocked(@UserIdInt int userId) {
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final String systemSpeechRecognizer =
mContext.getString(com.android.internal.R.string.config_systemSpeechRecognizer);
final String currentDefaultVoiceImeId = settings.getDefaultVoiceInputMethod();
@@ -5349,9 +5375,10 @@
return;
}
if (DEBUG) {
- Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme);
+ Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme
+ + " userId:" + userId);
}
- setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true);
+ setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true, userId);
settings.putDefaultVoiceInputMethod(newSystemVoiceIme.getId());
}
@@ -5363,11 +5390,11 @@
* @param id ID of the IME is to be manipulated. It is OK to pass IME ID that is currently
* not recognized by the system
* @param enabled {@code true} if {@code id} needs to be enabled
+ * @param userId the user ID to be updated
* @return {@code true} if the IME was previously enabled
*/
@GuardedBy("ImfLock.class")
- private boolean setInputMethodEnabledLocked(String id, boolean enabled) {
- final int userId = mCurrentUserId;
+ private boolean setInputMethodEnabledLocked(String id, boolean enabled, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (enabled) {
final String enabledImeIdsStr = settings.getEnabledInputMethodsStr();
@@ -5391,9 +5418,9 @@
if (bindingController.getDeviceIdToShowIme() == DEVICE_ID_DEFAULT) {
// Disabled input method is currently selected, switch to another one.
final String selId = settings.getSelectedInputMethod();
- if (id.equals(selId) && !chooseNewDefaultIMELocked()) {
+ if (id.equals(selId) && !chooseNewDefaultIMELocked(userId)) {
Slog.i(TAG, "Can't find new IME, unsetting the current input method.");
- resetSelectedInputMethodAndSubtypeLocked("");
+ resetSelectedInputMethodAndSubtypeLocked("", userId);
}
} else if (id.equals(settings.getSelectedDefaultDeviceInputMethod())) {
// Disabled default device IME while using a virtual device one, choose a
@@ -5416,11 +5443,10 @@
@GuardedBy("ImfLock.class")
private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId,
- boolean setSubtypeOnly) {
- final int userId = mCurrentUserId;
+ boolean setSubtypeOnly, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final var bindingController = getInputMethodBindingController(userId);
- settings.saveCurrentInputMethodAndSubtypeToHistory(getSelectedMethodIdLocked(),
+ settings.saveCurrentInputMethodAndSubtypeToHistory(bindingController.getSelectedMethodId(),
bindingController.getCurrentSubtype());
// Set Subtype here
@@ -5439,7 +5465,7 @@
newSubtypeHashcode = INVALID_SUBTYPE_HASHCODE;
// If the subtype is not specified, choose the most applicable one
// TODO(b/347083680): The method below has questionable behaviors.
- newSubtype = getCurrentInputMethodSubtypeLocked();
+ newSubtype = bindingController.getCurrentInputMethodSubtype();
}
}
settings.putSelectedSubtype(newSubtypeHashcode);
@@ -5453,12 +5479,13 @@
}
@GuardedBy("ImfLock.class")
- private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) {
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme,
+ @UserIdInt int userId) {
+ final var bindingController = getInputMethodBindingController(userId);
bindingController.setDisplayIdToShowIme(INVALID_DISPLAY);
bindingController.setDeviceIdToShowIme(DEVICE_ID_DEFAULT);
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
settings.putSelectedDefaultDeviceInputMethod(null);
InputMethodInfo imi = settings.getMethodMap().get(newDefaultIme);
@@ -5475,7 +5502,7 @@
}
}
}
- setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false);
+ setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false, userId);
}
/**
@@ -5492,54 +5519,13 @@
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
- if (mCurrentUserId == userId) {
- // TODO(b/347083680): The method below has questionable behaviors.
- return getCurrentInputMethodSubtypeLocked();
- }
-
- return InputMethodSettingsRepository.get(userId)
- .getCurrentInputMethodSubtypeForNonCurrentUsers();
+ final var bindingController = getInputMethodBindingController(userId);
+ // TODO(b/347083680): The method below has questionable behaviors.
+ return bindingController.getCurrentInputMethodSubtype();
}
}
/**
- * Returns the current {@link InputMethodSubtype} for the current user.
- *
- * <p>CAVEATS: You must also update
- * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}
- * when you update the algorithm of this method.</p>
- *
- * <p>TODO: Address code duplication between this and
- * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}.</p>
- *
- * <p>Also this method has had questionable behaviors:</p>
- * <ul>
- * <li>Calling this method can update {@link #mCurrentSubtype}.</li>
- * <li>This method may return {@link #mCurrentSubtype} as-is, even if it does not belong
- * to the current IME.</li>
- * </ul>
- * <p>TODO(b/347083680): Address above issues.</p>
- */
- @GuardedBy("ImfLock.class")
- InputMethodSubtype getCurrentInputMethodSubtypeLocked() {
- final int userId = mCurrentUserId;
- final var selectedMethodId = getInputMethodBindingController(userId).getSelectedMethodId();
- if (selectedMethodId == null) {
- return null;
- }
- final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- final InputMethodInfo imi = settings.getMethodMap().get(selectedMethodId);
- if (imi == null || imi.getSubtypeCount() == 0) {
- return null;
- }
- final var bindingController = getInputMethodBindingController(userId);
- final var subtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
- bindingController.getCurrentSubtype());
- bindingController.setCurrentSubtype(subtype);
- return subtype;
- }
-
- /**
* Returns the default {@link InputMethodInfo} for the specific userId.
*
* @param userId user ID to query
@@ -5559,7 +5545,7 @@
.contains(settings.getMethodMap().get(imeId))) {
return false; // IME is not found or not enabled.
}
- setInputMethodLocked(imeId, NOT_A_SUBTYPE_ID);
+ setInputMethodLocked(imeId, NOT_A_SUBTYPE_ID, userId);
return true;
}
if (!settings.getMethodMap().containsKey(imeId)
@@ -5601,15 +5587,15 @@
}
@GuardedBy("ImfLock.class")
- private void switchKeyboardLayoutLocked(int direction) {
- final int userId = mCurrentUserId;
+ private void switchKeyboardLayoutLocked(int direction, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- final InputMethodInfo currentImi = settings.getMethodMap().get(getSelectedMethodIdLocked());
+ final var bindingController = getInputMethodBindingController(userId);
+ final InputMethodInfo currentImi = settings.getMethodMap().get(
+ bindingController.getSelectedMethodId());
if (currentImi == null) {
return;
}
- final var bindingController = getInputMethodBindingController(userId);
final InputMethodSubtypeHandle currentSubtypeHandle =
InputMethodSubtypeHandle.of(currentImi, bindingController.getCurrentSubtype());
final InputMethodSubtypeHandle nextSubtypeHandle =
@@ -5626,7 +5612,7 @@
final int subtypeCount = nextImi.getSubtypeCount();
if (subtypeCount == 0) {
if (nextSubtypeHandle.equals(InputMethodSubtypeHandle.of(nextImi, null))) {
- setInputMethodLocked(nextImi.getId(), NOT_A_SUBTYPE_ID);
+ setInputMethodLocked(nextImi.getId(), NOT_A_SUBTYPE_ID, userId);
}
return;
}
@@ -5634,7 +5620,7 @@
for (int i = 0; i < subtypeCount; ++i) {
if (nextSubtypeHandle.equals(
InputMethodSubtypeHandle.of(nextImi, nextImi.getSubtypeAt(i)))) {
- setInputMethodLocked(nextImi.getId(), i);
+ setInputMethodLocked(nextImi.getId(), i, userId);
return;
}
}
@@ -5704,7 +5690,7 @@
return false; // IME is not found.
}
if (userId == mCurrentUserId) {
- setInputMethodEnabledLocked(imeId, enabled);
+ setInputMethodEnabledLocked(imeId, enabled, userId);
return true;
}
if (enabled) {
@@ -5751,7 +5737,8 @@
//TODO(b/150843766): Check if Input Token is valid.
final IBinder curHostInputToken;
synchronized (ImfLock.class) {
- if (displayId != getCurTokenDisplayIdLocked()) {
+ final var bindingController = getInputMethodBindingController(userId);
+ if (displayId != bindingController.getCurTokenDisplayId()) {
return false;
}
curHostInputToken = getInputMethodBindingController(userId).getCurHostInputToken();
@@ -5765,7 +5752,10 @@
@Override
public void reportImeControl(@Nullable IBinder windowToken) {
synchronized (ImfLock.class) {
- if (mImeBindingState.mFocusedWindow != windowToken) {
+ // TODO(b/305849394): Need to infer userId or get userId from callers.
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
+ if (userData.mImeBindingState.mFocusedWindow != windowToken) {
// A perceptible value was set for the focused window, but it is no longer in
// control, so we reset the perceptible for the window passed as argument.
// TODO(b/314149476): Investigate whether this logic is still relevant, if not
@@ -5778,10 +5768,13 @@
@Override
public void onImeParentChanged(int displayId) {
synchronized (ImfLock.class) {
+ // TODO(b/305849394): Need to infer userId or get userId from callers.
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
// Hide the IME method menu only when the IME surface parent is changed by the
// input target changed, in case seeing the dialog dismiss flickering during
// the next focused window starting the input connection.
- if (mLastImeTargetWindow != mImeBindingState.mFocusedWindow) {
+ if (mLastImeTargetWindow != userData.mImeBindingState.mFocusedWindow) {
mMenuController.hideInputMethodMenuLocked();
}
}
@@ -5804,33 +5797,36 @@
public void onSessionForAccessibilityCreated(int accessibilityConnectionId,
IAccessibilityInputMethodSession session, @UserIdInt int userId) {
synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
// TODO(b/305829876): Implement user ID verification
- if (mCurClient != null) {
- clearClientSessionForAccessibilityLocked(mCurClient, accessibilityConnectionId);
- mCurClient.mAccessibilitySessions.put(
+ if (userData.mCurClient != null) {
+ clearClientSessionForAccessibilityLocked(userData.mCurClient,
+ accessibilityConnectionId);
+ userData.mCurClient.mAccessibilitySessions.put(
accessibilityConnectionId,
- new AccessibilitySessionState(mCurClient,
+ new AccessibilitySessionState(userData.mCurClient,
accessibilityConnectionId,
session));
attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY,
- true);
+ true, userId);
- final SessionState sessionState = mCurClient.mCurSession;
+ final SessionState sessionState = userData.mCurClient.mCurSession;
final IInputMethodSession imeSession = sessionState == null
? null : sessionState.mSession;
final SparseArray<IAccessibilityInputMethodSession>
accessibilityInputMethodSessions =
createAccessibilityInputMethodSessions(
- mCurClient.mAccessibilitySessions);
+ userData.mCurClient.mAccessibilitySessions);
final InputBindResult res = new InputBindResult(
InputBindResult.ResultCode.SUCCESS_WITH_ACCESSIBILITY_SESSION,
imeSession, accessibilityInputMethodSessions, /* channel= */ null,
bindingController.getCurId(),
bindingController.getSequenceNumber(),
/* isInputMethodSuppressingSpellChecker= */ false);
- mCurClient.mClient.onBindAccessibilityService(res, accessibilityConnectionId);
+ userData.mCurClient.mClient.onBindAccessibilityService(res,
+ accessibilityConnectionId);
}
}
}
@@ -5839,33 +5835,34 @@
public void unbindAccessibilityFromCurrentClient(int accessibilityConnectionId,
@UserIdInt int userId) {
synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(mCurrentUserId);
+ final var bindingController = getInputMethodBindingController(userId);
+ final var userData = getUserData(userId);
// TODO(b/305829876): Implement user ID verification
- if (mCurClient != null) {
+ if (userData.mCurClient != null) {
if (DEBUG) {
Slog.v(TAG, "unbindAccessibilityFromCurrentClientLocked: client="
- + mCurClient.mClient.asBinder());
+ + userData.mCurClient.mClient.asBinder());
}
// A11yManagerService unbinds the disabled accessibility service. We don't need
// to do it here.
- mCurClient.mClient.onUnbindAccessibilityService(
+ userData.mCurClient.mClient.onUnbindAccessibilityService(
bindingController.getSequenceNumber(),
accessibilityConnectionId);
}
// We only have sessions when we bound to an input method. Remove this session
// from all clients.
- if (getCurMethodLocked() != null) {
+ if (bindingController.getCurMethod() != null) {
// TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
@SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession =
c -> clearClientSessionForAccessibilityLocked(c,
accessibilityConnectionId);
mClientController.forAllClients(clearClientSession);
- AccessibilitySessionState session = mEnabledAccessibilitySessions.get(
+ AccessibilitySessionState session = userData.mEnabledAccessibilitySessions.get(
accessibilityConnectionId);
if (session != null) {
finishSessionForAccessibilityLocked(session);
- mEnabledAccessibilitySessions.remove(accessibilityConnectionId);
+ userData.mEnabledAccessibilitySessions.remove(accessibilityConnectionId);
}
}
}
@@ -5882,14 +5879,15 @@
public void onSwitchKeyboardLayoutShortcut(int direction, int displayId,
IBinder targetWindowToken) {
synchronized (ImfLock.class) {
- switchKeyboardLayoutLocked(direction);
+ // TODO(b/305849394): Infer userId from displayId
+ switchKeyboardLayoutLocked(direction, mCurrentUserId);
}
}
}
@BinderThread
private IInputContentUriToken createInputContentUriToken(@Nullable IBinder token,
- @Nullable Uri contentUri, @Nullable String packageName) {
+ @Nullable Uri contentUri, @Nullable String packageName, @UserIdInt int imeUserId) {
if (token == null) {
throw new NullPointerException("token");
}
@@ -5906,15 +5904,6 @@
synchronized (ImfLock.class) {
final int uid = Binder.getCallingUid();
- final int imeUserId = UserHandle.getUserId(uid);
- if (imeUserId != mCurrentUserId) {
- // Currently concurrent multi-user is not supported here due to the remaining
- // dependency on mCurEditorInfo and mCurClient.
- // TODO(b/341558132): Remove this early-exit once it becomes multi-user ready.
- Slog.i(TAG, "Ignoring createInputContentUriToken due to user ID mismatch."
- + " imeUserId=" + imeUserId + " mCurrentUserId=" + mCurrentUserId);
- return null;
- }
final var bindingController = getInputMethodBindingController(imeUserId);
if (bindingController.getSelectedMethodId() == null) {
return null;
@@ -5927,16 +5916,16 @@
// We cannot simply distinguish a bad IME that reports an arbitrary package name from
// an unfortunate IME whose internal state is already obsolete due to the asynchronous
// nature of our system. Let's compare it with our internal record.
- // TODO(b/341558132): Use "imeUserId" to query per-user "curEditorInfo"
- final var curPackageName = mCurEditorInfo != null ? mCurEditorInfo.packageName : null;
+ final var userData = getUserData(imeUserId);
+ final var curPackageName = userData.mCurEditorInfo != null
+ ? userData.mCurEditorInfo.packageName : null;
if (!TextUtils.equals(curPackageName, packageName)) {
Slog.e(TAG, "Ignoring createInputContentUriToken mCurEditorInfo.packageName="
+ curPackageName + " packageName=" + packageName);
return null;
}
// This user ID can never be spoofed.
- // TODO(b/341558132): Use "imeUserId" to query per-user "curClient"
- final int appUserId = UserHandle.getUserId(mCurClient.mUid);
+ final int appUserId = UserHandle.getUserId(userData.mCurClient.mUid);
// This user ID may be invalid if "contentUri" embedded an invalid user ID.
final int contentUriOwnerUserId = ContentProvider.getUserIdFromUri(contentUri,
imeUserId);
@@ -5953,14 +5942,16 @@
}
@BinderThread
- private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen) {
+ private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen,
+ @UserIdInt int userId) {
synchronized (ImfLock.class) {
- if (!calledWithValidTokenLocked(token)) {
+ if (!calledWithValidTokenLocked(token, userId)) {
return;
}
- if (mCurClient != null && mCurClient.mClient != null) {
- mInFullscreenMode = fullscreen;
- mCurClient.mClient.reportFullscreenMode(fullscreen);
+ final var userData = getUserData(userId);
+ if (userData.mCurClient != null && userData.mCurClient.mClient != null) {
+ userData.mInFullscreenMode = fullscreen;
+ userData.mCurClient.mClient.reportFullscreenMode(fullscreen);
}
}
}
@@ -6053,7 +6044,9 @@
final Printer p = new PrintWriterPrinter(pw);
synchronized (ImfLock.class) {
- final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+ final int userId = mCurrentUserId;
+ final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
+ final var userData = getUserData(userId);
p.println("Current Input Method Manager state:");
final List<InputMethodInfo> methodList = settings.getMethodList();
int numImes = methodList.size();
@@ -6083,16 +6076,16 @@
mClientController.forAllClients(clientControllerDump);
final var bindingController = getInputMethodBindingController(mCurrentUserId);
p.println(" mCurrentUserId=" + mCurrentUserId);
- p.println(" mCurMethodId=" + getSelectedMethodIdLocked());
- client = mCurClient;
+ p.println(" mCurMethodId=" + bindingController.getSelectedMethodId());
+ client = userData.mCurClient;
p.println(" mCurClient=" + client + " mCurSeq="
+ bindingController.getSequenceNumber());
p.println(" mFocusedWindowPerceptible=" + mFocusedWindowPerceptible);
- mImeBindingState.dump(/* prefix= */ " ", p);
+ userData.mImeBindingState.dump(/* prefix= */ " ", p);
p.println(" mCurId=" + bindingController.getCurId()
+ " mHaveConnection=" + bindingController.hasMainConnection()
- + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound="
+ + " mBoundToMethod=" + userData.mBoundToMethod + " mVisibleBound="
+ bindingController.isVisibleBound());
p.println(" mUserDataRepository=");
@@ -6103,20 +6096,32 @@
p.println(" hasMainConnection="
+ u.mBindingController.hasMainConnection());
p.println(" isVisibleBound=" + u.mBindingController.isVisibleBound());
- p.println(" mSwitchingController:");
+ p.println(" boundToMethod=" + u.mBoundToMethod);
+ p.println(" curClient=" + u.mCurClient);
+ if (u.mCurEditorInfo != null) {
+ p.println(" curEditorInfo:");
+ u.mCurEditorInfo.dump(p, " ", false /* dumpExtras */);
+ } else {
+ p.println(" curEditorInfo: null");
+ }
+ p.println(" imeBindingState:");
+ u.mImeBindingState.dump(" ", p);
+ p.println(" enabledSession=" + u.mEnabledSession);
+ p.println(" inFullscreenMode=" + u.mInFullscreenMode);
+ p.println(" switchingController:");
u.mSwitchingController.dump(p, " ");
};
mUserDataRepository.forAllUserData(userDataDump);
- p.println(" mCurToken=" + getCurTokenLocked());
- p.println(" mCurTokenDisplayId=" + getCurTokenDisplayIdLocked());
+ p.println(" mCurToken=" + bindingController.getCurToken());
+ p.println(" mCurTokenDisplayId=" + bindingController.getCurTokenDisplayId());
p.println(" mCurHostInputToken=" + bindingController.getCurHostInputToken());
p.println(" mCurIntent=" + bindingController.getCurIntent());
- method = getCurMethodLocked();
- p.println(" mCurMethod=" + getCurMethodLocked());
- p.println(" mEnabledSession=" + mEnabledSession);
+ method = bindingController.getCurMethod();
+ p.println(" mCurMethod=" + method);
+ p.println(" mEnabledSession=" + userData.mEnabledSession);
mVisibilityStateComputer.dump(pw, " ");
- p.println(" mInFullscreenMode=" + mInFullscreenMode);
+ p.println(" mInFullscreenMode=" + userData.mInFullscreenMode);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
p.println(" mExperimentalConcurrentMultiUserModeEnabled="
+ mExperimentalConcurrentMultiUserModeEnabled);
@@ -6152,20 +6157,24 @@
} else {
p.println("No input method client.");
}
-
- if (mImeBindingState.mFocusedWindowClient != null
- && client != mImeBindingState.mFocusedWindowClient) {
- p.println(" ");
- p.println("Warning: Current input method client doesn't match the last focused. "
- + "window.");
- p.println("Dumping input method client in the last focused window just in case.");
- p.println(" ");
- pw.flush();
- try {
- TransferPipe.dumpAsync(
- mImeBindingState.mFocusedWindowClient.mClient.asBinder(), fd, args);
- } catch (IOException | RemoteException e) {
- p.println("Failed to dump input method client in focused window: " + e);
+ synchronized (ImfLock.class) {
+ final int userId = mCurrentUserId;
+ final var userData = getUserData(userId);
+ if (userData.mImeBindingState.mFocusedWindowClient != null
+ && client != userData.mImeBindingState.mFocusedWindowClient) {
+ p.println(" ");
+ p.println("Warning: Current input method client doesn't match the last focused. "
+ + "window.");
+ p.println("Dumping input method client in the last focused window just in case.");
+ p.println(" ");
+ pw.flush();
+ try {
+ TransferPipe.dumpAsync(
+ userData.mImeBindingState.mFocusedWindowClient.mClient.asBinder(), fd,
+ args);
+ } catch (IOException | RemoteException e) {
+ p.println("Failed to dump input method client in focused window: " + e);
+ }
}
}
@@ -6489,7 +6498,7 @@
if (enabled && !settings.getMethodMap().containsKey(imeId)) {
failedToEnableUnknownIme = true;
} else {
- previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled);
+ previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled, userId);
}
} else {
if (enabled) {
@@ -6601,18 +6610,21 @@
final List<InputMethodInfo> nextEnabledImes;
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (userId == mCurrentUserId) {
+ final var userData = getUserData(userId);
if (Flags.refactorInsetsController()) {
- if (mImeBindingState != null
- && mImeBindingState.mFocusedWindowClient != null
- && mImeBindingState.mFocusedWindowClient.mClient != null) {
- mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(
- false);
+ if (userData.mImeBindingState != null
+ && userData.mImeBindingState.mFocusedWindowClient != null
+ && userData.mImeBindingState.mFocusedWindowClient.mClient
+ != null) {
+ userData.mImeBindingState.mFocusedWindowClient.mClient
+ .setImeVisibility(false);
} else {
// TODO(b329229469): ImeTracker?
}
} else {
- hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
- SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
+ hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+ 0 /* flags */,
+ SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND, userId);
}
final var bindingController = getInputMethodBindingController(userId);
bindingController.unbindCurrentMethod();
@@ -6623,16 +6635,16 @@
mContext, settings.getMethodList());
toDisable.removeAll(defaultEnabled);
for (InputMethodInfo info : toDisable) {
- setInputMethodEnabledLocked(info.getId(), false);
+ setInputMethodEnabledLocked(info.getId(), false, userId);
}
for (InputMethodInfo info : defaultEnabled) {
- setInputMethodEnabledLocked(info.getId(), true);
+ setInputMethodEnabledLocked(info.getId(), true, userId);
}
// Choose new default IME, reset to none if no IME available.
- if (!chooseNewDefaultIMELocked()) {
- resetSelectedInputMethodAndSubtypeLocked(null);
+ if (!chooseNewDefaultIMELocked(userId)) {
+ resetSelectedInputMethodAndSubtypeLocked(null, userId);
}
- updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
+ updateInputMethodsFromSettingsLocked(true /* enabledMayChange */, userId);
InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
getPackageManagerForUser(mContext, settings.getUserId()),
settings.getEnabledInputMethodList());
@@ -6741,13 +6753,15 @@
* @param reason the reason why the IME request was created
*/
@NonNull
+ @GuardedBy("ImfLock.class")
private ImeTracker.Token createStatsTokenForFocusedClient(boolean show,
- @SoftInputShowHideReason int reason) {
- final int uid = mImeBindingState.mFocusedWindowClient != null
- ? mImeBindingState.mFocusedWindowClient.mUid
+ @SoftInputShowHideReason int reason, @UserIdInt int userId) {
+ final var userData = getUserData(userId);
+ final int uid = userData.mImeBindingState.mFocusedWindowClient != null
+ ? userData.mImeBindingState.mFocusedWindowClient.mUid
: -1;
- final var packageName = mImeBindingState.mFocusedWindowEditorInfo != null
- ? mImeBindingState.mFocusedWindowEditorInfo.packageName
+ final var packageName = userData.mImeBindingState.mFocusedWindowEditorInfo != null
+ ? userData.mImeBindingState.mFocusedWindowEditorInfo.packageName
: "uid(" + uid + ")";
return ImeTracker.forLogging().onStart(packageName, uid,
@@ -6760,23 +6774,26 @@
private final InputMethodManagerService mImms;
@NonNull
private final IBinder mToken;
+ @UserIdInt
+ private final int mUserId;
InputMethodPrivilegedOperationsImpl(InputMethodManagerService imms,
- @NonNull IBinder token) {
+ @NonNull IBinder token, @UserIdInt int userId) {
mImms = imms;
mToken = token;
+ mUserId = userId;
}
@BinderThread
@Override
public void setImeWindowStatusAsync(int vis, int backDisposition) {
- mImms.setImeWindowStatus(mToken, vis, backDisposition);
+ mImms.setImeWindowStatus(mToken, vis, backDisposition, mUserId);
}
@BinderThread
@Override
public void reportStartInputAsync(IBinder startInputToken) {
- mImms.reportStartInput(mToken, startInputToken);
+ mImms.reportStartInput(mToken, startInputToken, mUserId);
}
@BinderThread
@@ -6792,7 +6809,7 @@
@SuppressWarnings("unchecked") final AndroidFuture<IBinder> typedFuture = future;
try {
typedFuture.complete(mImms.createInputContentUriToken(
- mToken, contentUri, packageName).asBinder());
+ mToken, contentUri, packageName, mUserId).asBinder());
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6801,7 +6818,7 @@
@BinderThread
@Override
public void reportFullscreenModeAsync(boolean fullscreen) {
- mImms.reportFullscreenMode(mToken, fullscreen);
+ mImms.reportFullscreenMode(mToken, fullscreen, mUserId);
}
@BinderThread
@@ -6809,7 +6826,7 @@
public void setInputMethod(String id, AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.setInputMethod(mToken, id);
+ mImms.setInputMethod(mToken, id, mUserId);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6822,7 +6839,7 @@
AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.setInputMethodAndSubtype(mToken, id, subtype);
+ mImms.setInputMethodAndSubtype(mToken, id, subtype, mUserId);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6836,7 +6853,7 @@
AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.hideMySoftInput(mToken, statsToken, flags, reason);
+ mImms.hideMySoftInput(mToken, statsToken, flags, reason, mUserId);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6850,7 +6867,7 @@
AndroidFuture future /* T=Void */) {
@SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
try {
- mImms.showMySoftInput(mToken, statsToken, flags, reason);
+ mImms.showMySoftInput(mToken, statsToken, flags, reason, mUserId);
typedFuture.complete(null);
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
@@ -6860,7 +6877,7 @@
@BinderThread
@Override
public void updateStatusIconAsync(String packageName, @DrawableRes int iconId) {
- mImms.updateStatusIcon(mToken, packageName, iconId);
+ mImms.updateStatusIcon(mToken, packageName, iconId, mUserId);
}
@BinderThread
@@ -6868,7 +6885,7 @@
public void switchToPreviousInputMethod(AndroidFuture future /* T=Boolean */) {
@SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
try {
- typedFuture.complete(mImms.switchToPreviousInputMethod(mToken));
+ typedFuture.complete(mImms.switchToPreviousInputMethod(mToken, mUserId));
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6880,7 +6897,8 @@
AndroidFuture future /* T=Boolean */) {
@SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
try {
- typedFuture.complete(mImms.switchToNextInputMethod(mToken, onlyCurrentIme));
+ typedFuture.complete(mImms.switchToNextInputMethod(mToken, onlyCurrentIme,
+ mUserId));
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6891,7 +6909,7 @@
public void shouldOfferSwitchingToNextInputMethod(AndroidFuture future /* T=Boolean */) {
@SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
try {
- typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken));
+ typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken, mUserId));
} catch (Throwable e) {
typedFuture.completeExceptionally(e);
}
@@ -6900,20 +6918,20 @@
@BinderThread
@Override
public void notifyUserActionAsync() {
- mImms.notifyUserAction(mToken);
+ mImms.notifyUserAction(mToken, mUserId);
}
@BinderThread
@Override
public void applyImeVisibilityAsync(IBinder windowToken, boolean setVisible,
@NonNull ImeTracker.Token statsToken) {
- mImms.applyImeVisibility(mToken, windowToken, setVisible, statsToken);
+ mImms.applyImeVisibility(mToken, windowToken, setVisible, statsToken, mUserId);
}
@BinderThread
@Override
public void onStylusHandwritingReady(int requestId, int pid) {
- mImms.onStylusHandwritingReady(requestId, pid);
+ mImms.onStylusHandwritingReady(requestId, pid, mUserId);
}
@BinderThread
@@ -6926,12 +6944,12 @@
@Override
public void switchKeyboardLayoutAsync(int direction) {
synchronized (ImfLock.class) {
- if (!mImms.calledWithValidTokenLocked(mToken)) {
+ if (!mImms.calledWithValidTokenLocked(mToken, mUserId)) {
return;
}
final long ident = Binder.clearCallingIdentity();
try {
- mImms.switchKeyboardLayoutLocked(direction);
+ mImms.switchKeyboardLayoutLocked(direction, mUserId);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index 326ef7e..656c87d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -79,16 +79,17 @@
if (DEBUG) Slog.v(TAG, "Show switching menu. showAuxSubtypes=" + showAuxSubtypes);
final int userId = mService.getCurrentImeUserIdLocked();
+ final var bindingController = mService.getInputMethodBindingController(userId);
hideInputMethodMenuLocked();
if (preferredInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
final InputMethodSubtype currentSubtype =
- mService.getCurrentInputMethodSubtypeLocked();
+ bindingController.getCurrentInputMethodSubtype();
if (currentSubtype != null) {
- final String curMethodId = mService.getSelectedMethodIdLocked();
+ final String curMethodId = bindingController.getSelectedMethodId();
final InputMethodInfo currentImi =
- mService.queryInputMethodForCurrentUserLocked(curMethodId);
+ InputMethodSettingsRepository.get(userId).getMethodMap().get(curMethodId);
preferredInputMethodSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(
currentImi, currentSubtype.hashCode());
}
@@ -179,7 +180,7 @@
if (subtypeId < 0 || subtypeId >= im.getSubtypeCount()) {
subtypeId = NOT_A_SUBTYPE_ID;
}
- mService.setInputMethodLocked(im.getId(), subtypeId);
+ mService.setInputMethodLocked(im.getId(), subtypeId, userId);
}
hideInputMethodMenuLocked();
}
@@ -200,7 +201,7 @@
attrs.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
attrs.setTitle("Select input method");
w.setAttributes(attrs);
- mService.updateSystemUiLocked();
+ mService.updateSystemUiLocked(userId);
mService.sendOnNavButtonFlagsChangedLocked();
mSwitchingDialog.show();
}
@@ -238,7 +239,9 @@
mSwitchingDialog = null;
mSwitchingDialogTitleView = null;
- mService.updateSystemUiLocked();
+ // TODO(b/305849394): Make InputMethodMenuController multi-user aware
+ final int userId = mService.getCurrentImeUserIdLocked();
+ mService.updateSystemUiLocked(userId);
mService.sendOnNavButtonFlagsChangedLocked();
mDialogBuilder = null;
mIms = null;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
index 5569e1e..0152158 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
@@ -571,57 +571,6 @@
}
}
- /**
- * A variant of {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()} for
- * non-current users.
- *
- * <p>TODO: Address code duplication between this and
- * {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()}.</p>
- *
- * @return {@link InputMethodSubtype} if exists. {@code null} otherwise.
- */
- @Nullable
- InputMethodSubtype getCurrentInputMethodSubtypeForNonCurrentUsers() {
- final String selectedMethodId = getSelectedInputMethod();
- if (selectedMethodId == null) {
- return null;
- }
- final InputMethodInfo imi = mMethodMap.get(selectedMethodId);
- if (imi == null || imi.getSubtypeCount() == 0) {
- return null;
- }
-
- final int subtypeHashCode = getSelectedInputMethodSubtypeHashCode();
- if (subtypeHashCode != INVALID_SUBTYPE_HASHCODE) {
- final int subtypeIndex = SubtypeUtils.getSubtypeIdFromHashCode(imi,
- subtypeHashCode);
- if (subtypeIndex >= 0) {
- return imi.getSubtypeAt(subtypeIndex);
- }
- }
-
- // If there are no selected subtypes, the framework will try to find the most applicable
- // subtype from explicitly or implicitly enabled subtypes.
- final List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
- getEnabledInputMethodSubtypeList(imi, true);
- // If there is only one explicitly or implicitly enabled subtype, just returns it.
- if (explicitlyOrImplicitlyEnabledSubtypes.isEmpty()) {
- return null;
- }
- if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
- return explicitlyOrImplicitlyEnabledSubtypes.get(0);
- }
- final String locale = SystemLocaleWrapper.get(mUserId).get(0).toString();
- final InputMethodSubtype subtype = SubtypeUtils.findLastResortApplicableSubtype(
- explicitlyOrImplicitlyEnabledSubtypes, SubtypeUtils.SUBTYPE_MODE_KEYBOARD,
- locale, true);
- if (subtype != null) {
- return subtype;
- }
- return SubtypeUtils.findLastResortApplicableSubtype(
- explicitlyOrImplicitlyEnabledSubtypes, null, locale, true);
- }
-
@NonNull
AdditionalSubtypeMap getNewAdditionalSubtypeMap(@NonNull String imeId,
@NonNull ArrayList<InputMethodSubtype> subtypes,
diff --git a/services/core/java/com/android/server/inputmethod/UserDataRepository.java b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
index 3da4a14..48284fb 100644
--- a/services/core/java/com/android/server/inputmethod/UserDataRepository.java
+++ b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
@@ -17,12 +17,18 @@
package com.android.server.inputmethod;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.pm.UserInfo;
import android.os.Handler;
import android.util.SparseArray;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ImeTracker;
+import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
+import com.android.internal.inputmethod.IRemoteInputConnection;
import com.android.server.pm.UserManagerInternal;
import java.util.function.Consumer;
@@ -96,6 +102,78 @@
final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController;
/**
+ * Have we called mCurMethod.bindInput()?
+ */
+ @GuardedBy("ImfLock.class")
+ boolean mBoundToMethod = false;
+
+ /**
+ * Have we called bindInput() for accessibility services?
+ */
+ @GuardedBy("ImfLock.class")
+ boolean mBoundToAccessibility;
+
+ @GuardedBy("ImfLock.class")
+ @NonNull
+ ImeBindingState mImeBindingState = ImeBindingState.newEmptyState();
+
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ ClientState mCurClient = null;
+
+ @GuardedBy("ImfLock.class")
+ boolean mInFullscreenMode;
+
+ /**
+ * The {@link IRemoteInputConnection} last provided by the current client.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ IRemoteInputConnection mCurInputConnection;
+
+ /**
+ * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to
+ * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ ImeOnBackInvokedDispatcher mCurImeDispatcher;
+
+ /**
+ * The {@link IRemoteAccessibilityInputConnection} last provided by the current client.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection;
+
+ /**
+ * The {@link EditorInfo} last provided by the current client.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ EditorInfo mCurEditorInfo;
+
+ /**
+ * The token tracking the current IME show request that is waiting for a connection to an
+ * IME, otherwise {@code null}.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ ImeTracker.Token mCurStatsToken;
+
+ /**
+ * Currently enabled session.
+ */
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ InputMethodManagerService.SessionState mEnabledSession;
+
+ @GuardedBy("ImfLock.class")
+ @Nullable
+ SparseArray<InputMethodManagerService.AccessibilitySessionState>
+ mEnabledAccessibilitySessions = new SparseArray<>();
+
+ /**
* Intended to be instantiated only from this file.
*/
private UserData(@UserIdInt int userId,
diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
index 757c07c..41aac32 100644
--- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
+++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
@@ -254,7 +254,7 @@
synchronized (ImfLock.class) {
ClientState cs = imms.getClientStateLocked(client);
if (cs != null) {
- imms.requestClientSessionLocked(cs);
+ imms.requestClientSessionLocked(cs, userId);
imms.requestClientSessionForAccessibilityLocked(cs);
}
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 7a722bc..a0aad52 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -81,7 +81,6 @@
import java.util.Objects;
import java.util.Optional;
import java.util.PriorityQueue;
-import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -162,8 +161,8 @@
new PriorityQueue<>(
Comparator.comparingLong(ReliableMessageRecord::getTimestamp));
- // The test mode manager that manages behaviors during test mode.
- private final TestModeManager mTestModeManager = new TestModeManager();
+ // The test mode manager that manages behaviors during test mode
+ private final ContextHubTestModeManager mTestModeManager = new ContextHubTestModeManager();
// The period of the recurring time
private static final int PERIOD_METRIC_QUERY_DAYS = 1;
@@ -226,17 +225,20 @@
@Override
public void handleNanoappMessage(short hostEndpointId, NanoAppMessage message,
List<String> nanoappPermissions, List<String> messagePermissions) {
- if (Flags.reliableMessageImplementation()
+ // Only process the message normally if not using test mode manager or if
+ // the test mode manager call returned false as this indicates it did not
+ // process the message.
+ boolean useTestModeManager = Flags.reliableMessageImplementation()
&& Flags.reliableMessageTestModeBehavior()
- && mIsTestModeEnabled.get()
- && mTestModeManager.handleNanoappMessage(mContextHubId, hostEndpointId,
- message, nanoappPermissions, messagePermissions)) {
- // The TestModeManager handled the nanoapp message, so return here.
- return;
+ && mIsTestModeEnabled.get();
+ if (!useTestModeManager
+ || !mTestModeManager.handleNanoappMessage(() -> {
+ handleClientMessageCallback(mContextHubId, hostEndpointId,
+ message, nanoappPermissions, messagePermissions);
+ }, message)) {
+ handleClientMessageCallback(mContextHubId, hostEndpointId,
+ message, nanoappPermissions, messagePermissions);
}
-
- handleClientMessageCallback(mContextHubId, hostEndpointId, message,
- nanoappPermissions, messagePermissions);
}
@Override
@@ -261,8 +263,6 @@
* Records a reliable message from a nanoapp for duplicate detection.
*/
private static class ReliableMessageRecord {
- public static final int TIMEOUT_NS = 1000000000;
-
public int mContextHubId;
public long mTimestamp;
public int mMessageSequenceNumber;
@@ -297,56 +297,8 @@
}
public boolean isExpired() {
- return mTimestamp + TIMEOUT_NS < SystemClock.elapsedRealtimeNanos();
- }
- }
-
- /**
- * A class to manage behaviors during test mode. This is used for testing.
- */
- private class TestModeManager {
- /**
- * Probability (in percent) of duplicating a message.
- */
- private static final int MESSAGE_DUPLICATION_PROBABILITY_PERCENT = 50;
-
- /**
- * The number of total messages to send when the duplicate event happens.
- */
- private static final int NUM_MESSAGES_TO_DUPLICATE = 3;
-
- /**
- * A probability percent for a certain event.
- */
- private static final int MAX_PROBABILITY_PERCENT = 100;
-
- private final Random mRandom = new Random();
-
- /**
- * @return whether the message was handled
- * @see ContextHubServiceCallback#handleNanoappMessage
- */
- public boolean handleNanoappMessage(int contextHubId,
- short hostEndpointId, NanoAppMessage message,
- List<String> nanoappPermissions, List<String> messagePermissions) {
- if (!message.isReliable()) {
- return false;
- }
-
- if (Flags.reliableMessageDuplicateDetectionService()
- && mRandom.nextInt(MAX_PROBABILITY_PERCENT)
- < MESSAGE_DUPLICATION_PROBABILITY_PERCENT) {
- Log.i(TAG, "[TEST MODE] Duplicating message ("
- + NUM_MESSAGES_TO_DUPLICATE
- + " sends) with message sequence number: "
- + message.getMessageSequenceNumber());
- for (int i = 0; i < NUM_MESSAGES_TO_DUPLICATE; ++i) {
- handleClientMessageCallback(contextHubId, hostEndpointId,
- message, nanoappPermissions, messagePermissions);
- }
- return true;
- }
- return false;
+ return mTimestamp + ContextHubTransactionManager.RELIABLE_MESSAGE_TIMEOUT.toNanos()
+ < SystemClock.elapsedRealtimeNanos();
}
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
index 6da7a65..2ec9bdb 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
@@ -27,53 +27,65 @@
*
* @hide
*/
-/* package */ abstract class ContextHubServiceTransaction {
+abstract class ContextHubServiceTransaction {
private final int mTransactionId;
+
@ContextHubTransaction.Type
private final int mTransactionType;
- /** The ID of the nanoapp this transaction is targeted for, null if not applicable. */
private final Long mNanoAppId;
- /**
- * The host package associated with this transaction.
- */
private final String mPackage;
- /**
- * The message sequence number associated with this transaction, null if not applicable.
- */
private final Integer mMessageSequenceNumber;
- /**
- * true if the transaction has already completed, false otherwise
- */
+ private long mNextRetryTime;
+
+ private long mTimeoutTime;
+
+ /** The number of times the transaction has been started (start function called). */
+ private int mNumCompletedStartCalls;
+
+ private final short mHostEndpointId;
+
private boolean mIsComplete = false;
- /* package */ ContextHubServiceTransaction(int id, int type, String packageName) {
+ ContextHubServiceTransaction(int id, int type, String packageName) {
mTransactionId = id;
mTransactionType = type;
mNanoAppId = null;
mPackage = packageName;
mMessageSequenceNumber = null;
+ mNextRetryTime = Long.MAX_VALUE;
+ mTimeoutTime = Long.MAX_VALUE;
+ mNumCompletedStartCalls = 0;
+ mHostEndpointId = Short.MAX_VALUE;
}
- /* package */ ContextHubServiceTransaction(int id, int type, long nanoAppId,
+ ContextHubServiceTransaction(int id, int type, long nanoAppId,
String packageName) {
mTransactionId = id;
mTransactionType = type;
mNanoAppId = nanoAppId;
mPackage = packageName;
mMessageSequenceNumber = null;
+ mNextRetryTime = Long.MAX_VALUE;
+ mTimeoutTime = Long.MAX_VALUE;
+ mNumCompletedStartCalls = 0;
+ mHostEndpointId = Short.MAX_VALUE;
}
- /* package */ ContextHubServiceTransaction(int id, int type, String packageName,
- int messageSequenceNumber) {
+ ContextHubServiceTransaction(int id, int type, String packageName,
+ int messageSequenceNumber, short hostEndpointId) {
mTransactionId = id;
mTransactionType = type;
mNanoAppId = null;
mPackage = packageName;
mMessageSequenceNumber = messageSequenceNumber;
+ mNextRetryTime = Long.MAX_VALUE;
+ mTimeoutTime = Long.MAX_VALUE;
+ mNumCompletedStartCalls = 0;
+ mHostEndpointId = hostEndpointId;
}
/**
@@ -95,7 +107,7 @@
*
* @param result the result of the transaction
*/
- /* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
+ void onTransactionComplete(@ContextHubTransaction.Result int result) {
}
/**
@@ -106,44 +118,51 @@
* @param result the result of the query
* @param nanoAppStateList the list of nanoapps given by the query response
*/
- /* package */ void onQueryResponse(
+ void onQueryResponse(
@ContextHubTransaction.Result int result, List<NanoAppState> nanoAppStateList) {
}
- /**
- * @return the ID of this transaction
- */
- /* package */ int getTransactionId() {
+ int getTransactionId() {
return mTransactionId;
}
- /**
- * @return the type of this transaction
- * @see ContextHubTransaction.Type
- */
@ContextHubTransaction.Type
- /* package */ int getTransactionType() {
+ int getTransactionType() {
return mTransactionType;
}
- /**
- * @return the message sequence number of this transaction
- */
Integer getMessageSequenceNumber() {
return mMessageSequenceNumber;
}
+ long getNextRetryTime() {
+ return mNextRetryTime;
+ }
+
+ long getTimeoutTime() {
+ return mTimeoutTime;
+ }
+
+ int getNumCompletedStartCalls() {
+ return mNumCompletedStartCalls;
+ }
+
+ short getHostEndpointId() {
+ return mHostEndpointId;
+ }
+
/**
* Gets the timeout period as defined in IContexthub.hal
*
* @return the timeout of this transaction in the specified time unit
*/
- /* package */ long getTimeout(TimeUnit unit) {
+ long getTimeout(TimeUnit unit) {
switch (mTransactionType) {
case ContextHubTransaction.TYPE_LOAD_NANOAPP:
return unit.convert(30L, TimeUnit.SECONDS);
case ContextHubTransaction.TYPE_RELIABLE_MESSAGE:
- return unit.convert(1000L, TimeUnit.MILLISECONDS);
+ return unit.convert(ContextHubTransactionManager.RELIABLE_MESSAGE_TIMEOUT.toNanos(),
+ TimeUnit.NANOSECONDS);
case ContextHubTransaction.TYPE_UNLOAD_NANOAPP:
case ContextHubTransaction.TYPE_ENABLE_NANOAPP:
case ContextHubTransaction.TYPE_DISABLE_NANOAPP:
@@ -159,14 +178,23 @@
*
* Should only be called as a result of a response from a Context Hub callback
*/
- /* package */ void setComplete() {
+ void setComplete() {
mIsComplete = true;
}
- /**
- * @return true if the transaction has already completed, false otherwise
- */
- /* package */ boolean isComplete() {
+ void setNextRetryTime(long nextRetryTime) {
+ mNextRetryTime = nextRetryTime;
+ }
+
+ void setTimeoutTime(long timeoutTime) {
+ mTimeoutTime = timeoutTime;
+ }
+
+ void setNumCompletedStartCalls(int numCompletedStartCalls) {
+ mNumCompletedStartCalls = numCompletedStartCalls;
+ }
+
+ boolean isComplete() {
return mIsComplete;
}
@@ -187,7 +215,18 @@
out.append(", messageSequenceNumber = ");
out.append(mMessageSequenceNumber);
}
+ if (mTransactionType == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) {
+ out.append(", nextRetryTime = ");
+ out.append(mNextRetryTime);
+ out.append(", timeoutTime = ");
+ out.append(mTimeoutTime);
+ out.append(", numCompletedStartCalls = ");
+ out.append(mNumCompletedStartCalls);
+ out.append(", hostEndpointId = ");
+ out.append(mHostEndpointId);
+ }
out.append(")");
+
return out.toString();
}
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
new file mode 100644
index 0000000..e50324e
--- /dev/null
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 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.location.contexthub;
+
+import android.chre.flags.Flags;
+import android.hardware.location.NanoAppMessage;
+import android.util.Log;
+
+import java.util.Random;
+
+/**
+ * A class to manage behaviors during test mode. This is used for testing.
+ * @hide
+ */
+public class ContextHubTestModeManager {
+ private static final String TAG = "ContextHubTestModeManager";
+
+ /** Probability (in percent) of duplicating a message. */
+ private static final int MESSAGE_DROP_PROBABILITY_PERCENT = 20;
+
+ /** Probability (in percent) of duplicating a message. */
+ private static final int MESSAGE_DUPLICATION_PROBABILITY_PERCENT = 20;
+
+ /** The number of total messages to send when the duplicate event happens. */
+ private static final int NUM_MESSAGES_TO_DUPLICATE = 3;
+
+ /** A probability percent for a certain event. */
+ private static final int MAX_PROBABILITY_PERCENT = 100;
+
+ private final Random mRandom = new Random();
+
+ /**
+ * @return whether the message was handled
+ * @see ContextHubServiceCallback#handleNanoappMessage
+ */
+ public boolean handleNanoappMessage(Runnable handleMessage, NanoAppMessage message) {
+ if (Flags.reliableMessageDuplicateDetectionService()
+ && message.isReliable()
+ && mRandom.nextInt(MAX_PROBABILITY_PERCENT)
+ < MESSAGE_DUPLICATION_PROBABILITY_PERCENT) {
+ Log.i(TAG, "[TEST MODE] Duplicating message ("
+ + NUM_MESSAGES_TO_DUPLICATE
+ + " sends) with message sequence number: "
+ + message.getMessageSequenceNumber());
+ for (int i = 0; i < NUM_MESSAGES_TO_DUPLICATE; ++i) {
+ handleMessage.run();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @return whether the message was handled
+ * @see IContextHubWrapper#sendMessageToContextHub
+ */
+ public boolean sendMessageToContextHub(NanoAppMessage message) {
+ if (Flags.reliableMessageRetrySupportService()
+ && message.isReliable()
+ && mRandom.nextInt(MAX_PROBABILITY_PERCENT)
+ < MESSAGE_DROP_PROBABILITY_PERCENT) {
+ Log.i(TAG, "[TEST MODE] Dropping message with message sequence number: "
+ + message.getMessageSequenceNumber());
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
index ec94e2b..1a449e0 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
@@ -16,19 +16,26 @@
package com.android.server.location.contexthub;
+import android.chre.flags.Flags;
import android.hardware.location.ContextHubTransaction;
import android.hardware.location.IContextHubTransactionCallback;
import android.hardware.location.NanoAppBinary;
import android.hardware.location.NanoAppMessage;
import android.hardware.location.NanoAppState;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.Log;
+import java.time.Duration;
import java.util.ArrayDeque;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Random;
+import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -47,34 +54,30 @@
/* package */ class ContextHubTransactionManager {
private static final String TAG = "ContextHubTransactionManager";
- /*
- * Maximum number of transaction requests that can be pending at a time
- */
+ public static final Duration RELIABLE_MESSAGE_TIMEOUT = Duration.ofSeconds(1);
+
private static final int MAX_PENDING_REQUESTS = 10000;
- /*
- * The proxy to talk to the Context Hub
- */
+ private static final int RELIABLE_MESSAGE_MAX_NUM_RETRY = 3;
+
+ private static final Duration RELIABLE_MESSAGE_RETRY_WAIT_TIME = Duration.ofMillis(250);
+
+ private static final Duration RELIABLE_MESSAGE_MIN_WAIT_TIME = Duration.ofNanos(1000);
+
private final IContextHubWrapper mContextHubProxy;
- /*
- * The manager for all clients for the service.
- */
private final ContextHubClientManager mClientManager;
- /*
- * The nanoapp state manager for the service
- */
private final NanoAppStateManager mNanoAppStateManager;
- /*
- * A queue containing the current transactions
- */
private final ArrayDeque<ContextHubServiceTransaction> mTransactionQueue = new ArrayDeque<>();
- /*
- * The next available transaction ID
- */
+ private final Map<Integer, ContextHubServiceTransaction> mReliableMessageTransactionMap =
+ new HashMap<>();
+
+ /** A set of host endpoint IDs that have an active pending transaction. */
+ private final Set<Short> mReliableMessageHostEndpointIdActiveSet = new HashSet<>();
+
private final AtomicInteger mNextAvailableId = new AtomicInteger();
/**
@@ -86,10 +89,12 @@
new AtomicInteger(new Random().nextInt(Integer.MAX_VALUE / 2));
/*
- * An executor and the future object for scheduling timeout timers
+ * An executor and the future object for scheduling timeout timers and
+ * for scheduling the processing of reliable message transactions.
*/
- private final ScheduledThreadPoolExecutor mTimeoutExecutor = new ScheduledThreadPoolExecutor(1);
+ private final ScheduledThreadPoolExecutor mExecutor = new ScheduledThreadPoolExecutor(1);
private ScheduledFuture<?> mTimeoutFuture = null;
+ private ScheduledFuture<?> mReliableMessageTransactionFuture = null;
/*
* The list of previous transaction records.
@@ -333,7 +338,7 @@
IContextHubTransactionCallback transactionCallback, String packageName) {
return new ContextHubServiceTransaction(mNextAvailableId.getAndIncrement(),
ContextHubTransaction.TYPE_RELIABLE_MESSAGE, packageName,
- mNextAvailableMessageSequenceNumber.getAndIncrement()) {
+ mNextAvailableMessageSequenceNumber.getAndIncrement(), hostEndpointId) {
@Override
/* package */ int onTransact() {
try {
@@ -416,16 +421,23 @@
return;
}
- if (mTransactionQueue.size() == MAX_PENDING_REQUESTS) {
+ if (mTransactionQueue.size() >= MAX_PENDING_REQUESTS
+ || mReliableMessageTransactionMap.size() >= MAX_PENDING_REQUESTS) {
throw new IllegalStateException("Transaction queue is full (capacity = "
+ MAX_PENDING_REQUESTS + ")");
}
- mTransactionQueue.add(transaction);
mTransactionRecordDeque.add(new TransactionRecord(transaction.toString()));
-
- if (mTransactionQueue.size() == 1) {
- startNextTransaction();
+ if (Flags.reliableMessageRetrySupportService()
+ && transaction.getTransactionType()
+ == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) {
+ mReliableMessageTransactionMap.put(transaction.getMessageSequenceNumber(), transaction);
+ mExecutor.execute(() -> processMessageTransactions());
+ } else {
+ mTransactionQueue.add(transaction);
+ if (mTransactionQueue.size() == 1) {
+ startNextTransaction();
+ }
}
}
@@ -455,26 +467,42 @@
/* package */
synchronized void onMessageDeliveryResponse(int messageSequenceNumber, boolean success) {
- ContextHubServiceTransaction transaction = mTransactionQueue.peek();
+ if (!Flags.reliableMessageRetrySupportService()) {
+ ContextHubServiceTransaction transaction = mTransactionQueue.peek();
+ if (transaction == null) {
+ Log.w(TAG, "Received unexpected transaction response (no transaction pending)");
+ return;
+ }
+
+ Integer transactionMessageSequenceNumber = transaction.getMessageSequenceNumber();
+ if (transaction.getTransactionType() != ContextHubTransaction.TYPE_RELIABLE_MESSAGE
+ || transactionMessageSequenceNumber == null
+ || transactionMessageSequenceNumber != messageSequenceNumber) {
+ Log.w(TAG, "Received unexpected message transaction response (expected message "
+ + "sequence number = "
+ + transaction.getMessageSequenceNumber()
+ + ", received messageSequenceNumber = " + messageSequenceNumber + ")");
+ return;
+ }
+
+ transaction.onTransactionComplete(success ? ContextHubTransaction.RESULT_SUCCESS :
+ ContextHubTransaction.RESULT_FAILED_AT_HUB);
+ removeTransactionAndStartNext();
+ return;
+ }
+
+ ContextHubServiceTransaction transaction =
+ mReliableMessageTransactionMap.get(messageSequenceNumber);
if (transaction == null) {
- Log.w(TAG, "Received unexpected transaction response (no transaction pending)");
+ Log.w(TAG, "Could not find reliable message transaction with message sequence number"
+ + messageSequenceNumber);
return;
}
- Integer transactionMessageSequenceNumber = transaction.getMessageSequenceNumber();
- if (transaction.getTransactionType() != ContextHubTransaction.TYPE_RELIABLE_MESSAGE
- || transactionMessageSequenceNumber == null
- || transactionMessageSequenceNumber != messageSequenceNumber) {
- Log.w(TAG, "Received unexpected message transaction response (expected message "
- + "sequence number = "
- + transaction.getMessageSequenceNumber()
- + ", received messageSequenceNumber = " + messageSequenceNumber + ")");
- return;
- }
-
- transaction.onTransactionComplete(success ? ContextHubTransaction.RESULT_SUCCESS :
- ContextHubTransaction.RESULT_FAILED_AT_HUB);
- removeTransactionAndStartNext();
+ completeMessageTransaction(transaction,
+ success ? ContextHubTransaction.RESULT_SUCCESS
+ : ContextHubTransaction.RESULT_FAILED_AT_HUB);
+ mExecutor.execute(() -> processMessageTransactions());
}
/**
@@ -503,6 +531,15 @@
*/
/* package */
synchronized void onHubReset() {
+ if (Flags.reliableMessageRetrySupportService()) {
+ Iterator<Map.Entry<Integer, ContextHubServiceTransaction>> iter =
+ mReliableMessageTransactionMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ completeMessageTransaction(iter.next().getValue(),
+ ContextHubTransaction.RESULT_FAILED_AT_HUB, iter);
+ }
+ }
+
ContextHubServiceTransaction transaction = mTransactionQueue.peek();
if (transaction == null) {
return;
@@ -566,7 +603,7 @@
long timeoutMs = transaction.getTimeout(TimeUnit.MILLISECONDS);
try {
- mTimeoutFuture = mTimeoutExecutor.schedule(
+ mTimeoutFuture = mExecutor.schedule(
onTimeoutFunc, timeoutMs, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Log.e(TAG, "Error when schedule a timer", e);
@@ -579,6 +616,138 @@
}
}
+ /**
+ * Processes message transactions, starting and completing them as needed.
+ * <p>
+ * This function is called when adding a message transaction or when a timer
+ * expires for an existing message transaction's retry or timeout. The
+ * internal processing loop will iterate at most twice as if one iteration
+ * completes a transaction, the next iteration can only start new transactions.
+ * If the first iteration does not complete any transaction, the loop will
+ * only iterate once.
+ * <p>
+ */
+ private synchronized void processMessageTransactions() {
+ if (!Flags.reliableMessageRetrySupportService()) {
+ return;
+ }
+
+ if (mReliableMessageTransactionFuture != null) {
+ mReliableMessageTransactionFuture.cancel(/* mayInterruptIfRunning= */ false);
+ mReliableMessageTransactionFuture = null;
+ }
+
+ long now = SystemClock.elapsedRealtimeNanos();
+ long nextExecutionTime = Long.MAX_VALUE;
+ boolean continueProcessing;
+ do {
+ continueProcessing = false;
+ Iterator<Map.Entry<Integer, ContextHubServiceTransaction>> iter =
+ mReliableMessageTransactionMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ ContextHubServiceTransaction transaction = iter.next().getValue();
+ short hostEndpointId = transaction.getHostEndpointId();
+ int numCompletedStartCalls = transaction.getNumCompletedStartCalls();
+ if (numCompletedStartCalls == 0
+ && mReliableMessageHostEndpointIdActiveSet.contains(hostEndpointId)) {
+ continue;
+ }
+
+ long nextRetryTime = transaction.getNextRetryTime();
+ long timeoutTime = transaction.getTimeoutTime();
+ boolean transactionTimedOut = timeoutTime <= now;
+ boolean transactionHitMaxRetries = nextRetryTime <= now
+ && numCompletedStartCalls > RELIABLE_MESSAGE_MAX_NUM_RETRY;
+ if (transactionTimedOut || transactionHitMaxRetries) {
+ completeMessageTransaction(transaction,
+ ContextHubTransaction.RESULT_FAILED_TIMEOUT, iter);
+ continueProcessing = true;
+ } else {
+ if (nextRetryTime <= now || numCompletedStartCalls <= 0) {
+ startMessageTransaction(transaction, now);
+ }
+
+ nextExecutionTime = Math.min(nextExecutionTime,
+ transaction.getNextRetryTime());
+ nextExecutionTime = Math.min(nextExecutionTime,
+ transaction.getTimeoutTime());
+ }
+ }
+ } while (continueProcessing);
+
+ if (nextExecutionTime < Long.MAX_VALUE) {
+ mReliableMessageTransactionFuture = mExecutor.schedule(
+ () -> processMessageTransactions(),
+ Math.max(nextExecutionTime - SystemClock.elapsedRealtimeNanos(),
+ RELIABLE_MESSAGE_MIN_WAIT_TIME.toNanos()),
+ TimeUnit.NANOSECONDS);
+ }
+ }
+
+ /**
+ * Completes a message transaction and removes it from the reliable message map.
+ *
+ * @param transaction The transaction to complete.
+ * @param result The result code.
+ */
+ private void completeMessageTransaction(ContextHubServiceTransaction transaction,
+ @ContextHubTransaction.Result int result) {
+ completeMessageTransaction(transaction, result, /* iter= */ null);
+ }
+
+ /**
+ * Completes a message transaction and removes it from the reliable message map using iter.
+ *
+ * @param transaction The transaction to complete.
+ * @param result The result code.
+ * @param iter The iterator for the reliable message map - used to remove the message directly.
+ */
+ private void completeMessageTransaction(ContextHubServiceTransaction transaction,
+ @ContextHubTransaction.Result int result,
+ Iterator<Map.Entry<Integer, ContextHubServiceTransaction>> iter) {
+ transaction.onTransactionComplete(result);
+
+ if (iter == null) {
+ mReliableMessageTransactionMap.remove(transaction.getMessageSequenceNumber());
+ } else {
+ iter.remove();
+ }
+ mReliableMessageHostEndpointIdActiveSet.remove(transaction.getHostEndpointId());
+
+ Log.d(TAG, "Successfully completed reliable message transaction with "
+ + "message sequence number: " + transaction.getMessageSequenceNumber()
+ + " and result: " + result);
+ }
+
+ /**
+ * Starts a message transaction.
+ *
+ * @param transaction The transaction to start.
+ * @param now The now time.
+ */
+ private void startMessageTransaction(ContextHubServiceTransaction transaction, long now) {
+ int numCompletedStartCalls = transaction.getNumCompletedStartCalls();
+ @ContextHubTransaction.Result int result = transaction.onTransact();
+ if (result == ContextHubTransaction.RESULT_SUCCESS) {
+ Log.d(TAG, "Successfully "
+ + (numCompletedStartCalls == 0 ? "started" : "retried")
+ + " reliable message transaction with message sequence number: "
+ + transaction.getMessageSequenceNumber());
+ } else {
+ Log.w(TAG, "Could not start reliable message transaction with "
+ + "message sequence number: "
+ + transaction.getMessageSequenceNumber()
+ + ", result: " + result);
+ }
+
+ transaction.setNextRetryTime(now + RELIABLE_MESSAGE_RETRY_WAIT_TIME.toNanos());
+ if (transaction.getTimeoutTime() == Long.MAX_VALUE) { // first time starting transaction
+ transaction.setTimeoutTime(now + RELIABLE_MESSAGE_TIMEOUT.toNanos());
+ }
+ transaction.setNumCompletedStartCalls(numCompletedStartCalls + 1);
+ mReliableMessageHostEndpointIdActiveSet.add(transaction.getHostEndpointId());
+ }
+
private int toStatsTransactionResult(@ContextHubTransaction.Result int result) {
switch (result) {
case ContextHubTransaction.RESULT_SUCCESS:
@@ -605,19 +774,34 @@
@Override
public String toString() {
- StringBuilder sb = new StringBuilder(100);
- ContextHubServiceTransaction[] arr;
+ StringBuilder sb = new StringBuilder();
+ int i = 0;
synchronized (this) {
- arr = mTransactionQueue.toArray(new ContextHubServiceTransaction[0]);
- }
- for (int i = 0; i < arr.length; i++) {
- sb.append(i + ": " + arr[i] + "\n");
- }
+ for (ContextHubServiceTransaction transaction: mTransactionQueue) {
+ sb.append(i);
+ sb.append(": ");
+ sb.append(transaction.toString());
+ sb.append("\n");
+ ++i;
+ }
- sb.append("Transaction History:\n");
- Iterator<TransactionRecord> iterator = mTransactionRecordDeque.descendingIterator();
- while (iterator.hasNext()) {
- sb.append(iterator.next() + "\n");
+ if (Flags.reliableMessageRetrySupportService()) {
+ for (ContextHubServiceTransaction transaction:
+ mReliableMessageTransactionMap.values()) {
+ sb.append(i);
+ sb.append(": ");
+ sb.append(transaction.toString());
+ sb.append("\n");
+ ++i;
+ }
+ }
+
+ sb.append("Transaction History:\n");
+ Iterator<TransactionRecord> iterator = mTransactionRecordDeque.descendingIterator();
+ while (iterator.hasNext()) {
+ sb.append(iterator.next());
+ sb.append("\n");
+ }
}
return sb.toString();
}
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index 552809b..4fc3d87 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -52,6 +52,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* @hide
@@ -432,10 +433,16 @@
// Use this thread in case where the execution requires to be on a service thread.
// For instance, AppOpsManager.noteOp requires the UPDATE_APP_OPS_STATS permission.
- private HandlerThread mHandlerThread =
+ private final HandlerThread mHandlerThread =
new HandlerThread("Context Hub AIDL callback", Process.THREAD_PRIORITY_BACKGROUND);
private Handler mHandler;
+ // True if test mode is enabled for the Context Hub
+ private final AtomicBoolean mIsTestModeEnabled = new AtomicBoolean(false);
+
+ // The test mode manager that manages behaviors during test mode
+ private final ContextHubTestModeManager mTestModeManager = new ContextHubTestModeManager();
+
private class ContextHubAidlCallback extends
android.hardware.contexthub.IContextHubCallback.Stub {
private final int mContextHubId;
@@ -549,6 +556,8 @@
} else {
Log.e(TAG, "mHandleServiceRestartCallback is not set");
}
+
+ mIsTestModeEnabled.set(false);
}
public Pair<List<ContextHubInfo>, List<String>> getHubs() throws RemoteException {
@@ -659,7 +668,17 @@
try {
var msg = ContextHubServiceUtil.createAidlContextHubMessage(
hostEndpointId, message);
- hub.sendMessageToHub(contextHubId, msg);
+
+ // Only process the message normally if not using test mode manager or if
+ // the test mode manager call returned false as this indicates it did not
+ // process the message.
+ boolean useTestModeManager = Flags.reliableMessageImplementation()
+ && Flags.reliableMessageTestModeBehavior()
+ && mIsTestModeEnabled.get();
+ if (!useTestModeManager || !mTestModeManager.sendMessageToContextHub(message)) {
+ hub.sendMessageToHub(contextHubId, msg);
+ }
+
return ContextHubTransaction.RESULT_SUCCESS;
} catch (RemoteException | ServiceSpecificException e) {
return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
@@ -828,6 +847,7 @@
return false;
}
+ mIsTestModeEnabled.set(enable);
try {
hub.setTestMode(enable);
return true;
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ae3a2afb..db4d68b 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1815,6 +1815,20 @@
}
}
+ @Override
+ public boolean writeRepairModeCredential(int userId) {
+ checkWritePermission();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mSpManager) {
+ long protectorId = getCurrentLskfBasedProtectorId(userId);
+ return mSpManager.writeRepairModeCredentialLocked(protectorId, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
/**
* @param savedCredential if the user is a profile with
* {@link UserManager#isCredentialSharableWithParent()} with unified challenge and
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 9ee05d8..3a0c1d0 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -17,7 +17,11 @@
package com.android.server.notification;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.NotificationChannel.NEWS_ID;
import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
+import static android.app.NotificationChannel.PROMOTIONS_ID;
+import static android.app.NotificationChannel.RECS_ID;
+import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
@@ -1581,7 +1585,11 @@
boolean includeChannel = (includeDeleted || !nc.isDeleted())
&& (activeChannelFilter == null
|| (includeBlocked && nc.getImportance() == IMPORTANCE_NONE)
- || activeChannelFilter.contains(nc.getId()));
+ || activeChannelFilter.contains(nc.getId()))
+ && !PROMOTIONS_ID.equals(nc.getId())
+ && !NEWS_ID.equals(nc.getId())
+ && !SOCIAL_MEDIA_ID.equals(nc.getId())
+ && !RECS_ID.equals(nc.getId());
if (includeChannel) {
if (nc.getGroup() != null) {
if (r.groups.get(nc.getGroup()) != null) {
diff --git a/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java b/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java
new file mode 100644
index 0000000..58b14b1
--- /dev/null
+++ b/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2024 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.pm;
+
+import static android.media.AudioAttributes.USAGE_ALARM;
+
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.media.AudioFocusInfo;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
+import android.media.audiopolicy.AudioPolicy;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.Vibrator;
+import android.util.Log;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+public class BackgroundUserSoundNotifier {
+
+ private static final boolean DEBUG = false;
+ private static final String LOG_TAG = BackgroundUserSoundNotifier.class.getSimpleName();
+ public static final String BUSN_CHANNEL_ID = "bg_user_sound_channel";
+ public static final String BUSN_CHANNEL_NAME = "BackgroundUserSound";
+ private static final String ACTION_MUTE_SOUND = "com.android.server.ACTION_MUTE_BG_USER";
+ private static final String EXTRA_NOTIFICATION_ID = "com.android.server.EXTRA_CLIENT_UID";
+ private static final String EXTRA_CURRENT_USER_ID = "com.android.server.EXTRA_CURRENT_USER_ID";
+ private static final String ACTION_SWITCH_USER = "com.android.server.ACTION_SWITCH_TO_USER";
+ /** ID of user with notification displayed, -1 if notification is not showing*/
+ private int mUserWithNotification = -1;
+ private final Context mSystemUserContext;
+ @VisibleForTesting
+ final NotificationManager mNotificationManager;
+ private final UserManager mUserManager;
+
+ /**
+ * Facilitates the display of notifications to current user when there is an alarm or timer
+ * going off on background user and allows to manage the sound through actions.
+ */
+ public BackgroundUserSoundNotifier(Context context) {
+ mSystemUserContext = context;
+ mNotificationManager = mSystemUserContext.getSystemService(NotificationManager.class);
+ mUserManager = mSystemUserContext.getSystemService(UserManager.class);
+ NotificationChannel channel = new NotificationChannel(BUSN_CHANNEL_ID, BUSN_CHANNEL_NAME,
+ NotificationManager.IMPORTANCE_HIGH);
+ mNotificationManager.createNotificationChannel(channel);
+ setupFocusControlAudioPolicy();
+ }
+
+ private void setupFocusControlAudioPolicy() {
+ // Used to configure our audio policy to handle focus events.
+ // This gives us the ability to decide which audio focus requests to accept and bypasses
+ // the framework ducking logic.
+ ActivityManager am = mSystemUserContext.getSystemService(ActivityManager.class);
+
+ registerReceiver(am);
+ BackgroundUserListener bgUserListener = new BackgroundUserListener(mSystemUserContext);
+ AudioPolicy.Builder focusControlPolicyBuilder = new AudioPolicy.Builder(mSystemUserContext);
+ focusControlPolicyBuilder.setLooper(Looper.getMainLooper());
+
+ focusControlPolicyBuilder.setAudioPolicyFocusListener(bgUserListener);
+
+ AudioPolicy mFocusControlAudioPolicy = focusControlPolicyBuilder.build();
+ int status = mSystemUserContext.getSystemService(AudioManager.class)
+ .registerAudioPolicy(mFocusControlAudioPolicy);
+ if (status != AudioManager.SUCCESS) {
+ Log.w(LOG_TAG , "Could not register the service's focus"
+ + " control audio policy, error: " + status);
+ }
+ }
+
+ final class BackgroundUserListener extends AudioPolicy.AudioPolicyFocusListener {
+
+ Context mSystemContext;
+
+ BackgroundUserListener(Context systemContext) {
+ mSystemContext = systemContext;
+ }
+
+ @SuppressLint("MissingPermission")
+ public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {
+ try {
+ BackgroundUserSoundNotifier.this.notifyForegroundUserAboutSoundIfNecessary(afi,
+ mSystemContext.createContextAsUser(
+ UserHandle.of(ActivityManager.getCurrentUser()), 0));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @SuppressLint("MissingPermission")
+ public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {
+ BackgroundUserSoundNotifier.this.dismissNotificationIfNecessary(afi);
+ }
+ }
+
+ /**
+ * Registers a BroadcastReceiver for actions related to background user sound notifications.
+ * When ACTION_MUTE_SOUND is received, it mutes a background user's alarm sound.
+ * When ACTION_SWITCH_USER is received, a switch to the background user with alarm is started.
+ */
+ private void registerReceiver(ActivityManager service) {
+ BroadcastReceiver backgroundUserNotificationBroadcastReceiver = new BroadcastReceiver() {
+ @SuppressLint("MissingPermission")
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!(intent.hasExtra(EXTRA_NOTIFICATION_ID)
+ && intent.hasExtra(EXTRA_CURRENT_USER_ID)
+ && intent.hasExtra(Intent.EXTRA_USER_ID))) {
+ return;
+ }
+ final int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
+
+ if (DEBUG) {
+ Log.d(LOG_TAG,
+ "User with alarm id " + intent.getIntExtra(Intent.EXTRA_USER_ID,
+ -1) + " current user id " + intent.getIntExtra(
+ EXTRA_CURRENT_USER_ID, -1));
+ }
+ mNotificationManager.cancelAsUser(LOG_TAG, notificationId,
+ UserHandle.of(intent.getIntExtra(EXTRA_CURRENT_USER_ID, -1)));
+ if (ACTION_MUTE_SOUND.equals(intent.getAction())) {
+ final AudioManager audioManager =
+ mSystemUserContext.getSystemService(AudioManager.class);
+ if (audioManager != null) {
+ for (AudioPlaybackConfiguration apc :
+ audioManager.getActivePlaybackConfigurations()) {
+ if (apc.getAudioAttributes().getUsage() == USAGE_ALARM) {
+ if (apc.getPlayerProxy() != null) {
+ apc.getPlayerProxy().stop();
+ }
+ }
+ }
+ }
+ Vibrator vibrator = mSystemUserContext.getSystemService(Vibrator.class);
+ if (vibrator != null && vibrator.isVibrating()) {
+ vibrator.cancel();
+ }
+ } else if (ACTION_SWITCH_USER.equals(intent.getAction())) {
+ service.switchUser(intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
+ }
+ }
+ };
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_MUTE_SOUND);
+ filter.addAction(ACTION_SWITCH_USER);
+ mSystemUserContext.registerReceiver(backgroundUserNotificationBroadcastReceiver, filter,
+ Context.RECEIVER_NOT_EXPORTED);
+ }
+
+ /**
+ * Check if sound is coming from background user and show notification is required.
+ */
+ @VisibleForTesting
+ void notifyForegroundUserAboutSoundIfNecessary(AudioFocusInfo afi, Context
+ foregroundContext) throws RemoteException {
+ final int userId = UserHandle.getUserId(afi.getClientUid());
+ final int usage = afi.getAttributes().getUsage();
+ UserInfo userInfo = mUserManager.getUserInfo(userId);
+ if (userInfo != null && userId != foregroundContext.getUserId()) {
+ //TODO: b/349138482 - Add handling of cases when usage == USAGE_NOTIFICATION_RINGTONE
+ if (usage == USAGE_ALARM) {
+ Intent muteIntent = createIntent(ACTION_MUTE_SOUND, afi, foregroundContext, userId);
+ PendingIntent mutePI = PendingIntent.getBroadcast(mSystemUserContext, 0,
+ muteIntent, PendingIntent.FLAG_UPDATE_CURRENT
+ | PendingIntent.FLAG_IMMUTABLE);
+ Intent switchIntent = createIntent(ACTION_SWITCH_USER, afi, foregroundContext,
+ userId);
+ PendingIntent switchPI = PendingIntent.getBroadcast(mSystemUserContext, 0,
+ switchIntent, PendingIntent.FLAG_UPDATE_CURRENT
+ | PendingIntent.FLAG_IMMUTABLE);
+
+ mUserWithNotification = foregroundContext.getUserId();
+ mNotificationManager.notifyAsUser(LOG_TAG, afi.getClientUid(),
+ createNotification(userInfo.name, mutePI, switchPI, foregroundContext),
+ foregroundContext.getUser());
+ }
+ }
+ }
+
+ /**
+ * If notification is present, dismisses it. To be called when the relevant sound loses focus.
+ */
+ private void dismissNotificationIfNecessary(AudioFocusInfo afi) {
+ if (mUserWithNotification >= 0) {
+ mNotificationManager.cancelAsUser(LOG_TAG, afi.getClientUid(),
+ UserHandle.of(mUserWithNotification));
+ }
+ mUserWithNotification = -1;
+ }
+
+ private Intent createIntent(String intentAction, AudioFocusInfo afi, Context fgUserContext,
+ int userId) {
+ final Intent intent = new Intent(intentAction);
+ intent.putExtra(EXTRA_CURRENT_USER_ID, fgUserContext.getUserId());
+ intent.putExtra(EXTRA_NOTIFICATION_ID, afi.getClientUid());
+ intent.putExtra(Intent.EXTRA_USER_ID, userId);
+ return intent;
+ }
+
+ private Notification createNotification(String userName, PendingIntent muteIntent,
+ PendingIntent switchIntent, Context fgContext) {
+ final String title = fgContext.getString(R.string.bg_user_sound_notification_title_alarm,
+ userName);
+ final int icon = R.drawable.ic_audio_alarm;
+ final Notification.Action mute = new Notification.Action.Builder(null,
+ fgContext.getString(R.string.bg_user_sound_notification_button_mute),
+ muteIntent).build();
+ final Notification.Action switchUser = new Notification.Action.Builder(null,
+ fgContext.getString(R.string.bg_user_sound_notification_button_switch_user),
+ switchIntent).build();
+ return new Notification.Builder(mSystemUserContext, BUSN_CHANNEL_ID)
+ .setSmallIcon(icon)
+ .setTicker(title)
+ .setWhen(0)
+ .setOngoing(true)
+ .setColor(fgContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentIntent(muteIntent)
+ .setAutoCancel(true)
+ .setActions(mute, switchUser)
+ .setContentText(fgContext.getString(R.string.bg_user_sound_notification_message))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .build();
+ }
+}
+
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 6eac72d..173fc5c 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -2504,13 +2504,13 @@
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- private void enableRestrictedSettings(String pkgName, int appId, int userId) {
+ private void setAccessRestrictedSettingsMode(String pkgName, int appId, int userId, int mode) {
final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class);
final int uid = UserHandle.getUid(userId, appId);
appOpsManager.setMode(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
uid,
pkgName,
- AppOpsManager.MODE_ERRORED);
+ mode);
}
/**
@@ -2888,8 +2888,21 @@
mPm.notifyPackageChanged(packageName, request.getAppId());
}
- if (!android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
- || !android.security.Flags.extendEcmToAllSettings()) {
+ // Set the OP_ACCESS_RESTRICTED_SETTINGS op, which is used by ECM (see {@link
+ // EnhancedConfirmationManager}) as a persistent state denoting whether an app is
+ // currently guarded by ECM, not guarded by ECM, or (in Android V+) that this should
+ // be decided later.
+ if (android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
+ && android.security.Flags.extendEcmToAllSettings()) {
+ final int appId = request.getAppId();
+ mPm.mHandler.post(() -> {
+ for (int userId : firstUserIds) {
+ // MODE_DEFAULT means that the app's guardedness will be decided lazily
+ setAccessRestrictedSettingsMode(packageName, appId, userId,
+ AppOpsManager.MODE_DEFAULT);
+ }
+ });
+ } else {
// Apply restricted settings on potentially dangerous packages. Needs to happen
// after appOpsManager is notified of the new package
if (request.getPackageSource() == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE
@@ -2898,7 +2911,9 @@
final int appId = request.getAppId();
mPm.mHandler.post(() -> {
for (int userId : firstUserIds) {
- enableRestrictedSettings(packageName, appId, userId);
+ // MODE_ERRORED means that the app is explicitly guarded
+ setAccessRestrictedSettingsMode(packageName, appId, userId,
+ AppOpsManager.MODE_ERRORED);
}
});
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 00e9d8d..47a79a3 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1060,7 +1060,10 @@
final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission(
android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
== PackageManager.PERMISSION_GRANTED);
- final int targetPackageUid = snapshot.getPackageUid(packageName, 0, userId);
+ // Also query the package uid for archived packages, so that the user confirmation
+ // dialog can be displayed for updating archived apps.
+ final int targetPackageUid = snapshot.getPackageUid(packageName,
+ PackageManager.MATCH_ARCHIVED_PACKAGES, userId);
final boolean isUpdate = targetPackageUid != -1 || isApexSession();
final InstallSourceInfo existingInstallSourceInfo = isUpdate
? snapshot.getInstallSourceInfo(packageName, userId)
diff --git a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
index 90d6adc..630fcb6 100644
--- a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
+++ b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
@@ -185,7 +185,8 @@
removeAppKeySetData = true;
}
- if (!installRequest.isInstallSystem() && !isSystemPackage && !isApex
+ if ((installRequest.getScanFlags() & SCAN_BOOTING) == 0
+ && !installRequest.isInstallSystem() && !isSystemPackage && !isApex
&& signingDetails != null
&& systemPackage != null && systemPackage.getSigningDetails() != null
&& systemPackage.getSigningDetails().checkCapability(
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 7f4a5cb..b9a9d64f 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -58,6 +58,7 @@
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
+import android.app.AlarmManager;
import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
@@ -326,6 +327,12 @@
*/
private static final long PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_TIMEOUT_MS = 5 * 60 * 1000;
+ /**
+ * The time duration (in milliseconds) of the window length for the auto-lock message alarm
+ */
+ private static final long PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_ALARM_WINDOW_MS =
+ TimeUnit.SECONDS.toMillis(55);
+
// Tron counters
private static final String TRON_GUEST_CREATED = "users_guest_created";
private static final String TRON_USER_CREATED = "users_user_created";
@@ -334,6 +341,7 @@
private final Context mContext;
private final PackageManagerService mPm;
+
/**
* Lock for packages. If using with {@link #mUsersLock}, {@link #mPackagesLock} should be
* acquired first.
@@ -556,8 +564,15 @@
private KeyguardManager.KeyguardLockedStateListener mKeyguardLockedStateListener;
- /** Token to identify and remove already scheduled private space auto-lock messages */
- private static final Object PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN = new Object();
+ /**
+ * {@link android.app.AlarmManager.OnAlarmListener} to schedule an alarm to enable
+ * auto-locking private space after screen timeout
+ */
+ private PrivateSpaceAutoLockTimer mPrivateSpaceAutoLockTimer;
+
+ /** Tag representing the alarm manager timer for auto-locking private space */
+ private static final String PRIVATE_SPACE_AUTO_LOCK_TIMER_TAG = "PrivateSpaceAutoLockTimer";
+
/** Content observer to get callbacks for privte space autolock settings changes */
private final SettingsObserver mPrivateSpaceAutoLockSettingsObserver;
@@ -608,22 +623,28 @@
public void onReceive(Context context, Intent intent) {
if (isAutoLockForPrivateSpaceEnabled()) {
if (ACTION_SCREEN_OFF.equals(intent.getAction())) {
- Slog.d(LOG_TAG, "SCREEN_OFF broadcast received");
- maybeScheduleMessageToAutoLockPrivateSpace();
+ maybeScheduleAlarmToAutoLockPrivateSpace();
} else if (ACTION_SCREEN_ON.equals(intent.getAction())) {
Slog.d(LOG_TAG, "SCREEN_ON broadcast received, "
- + "removing queued message to auto-lock private space");
- // Remove any queued messages since the device is interactive again
- mHandler.removeCallbacksAndMessages(PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN);
+ + "removing pending alarms to auto-lock private space");
+ // Remove any pending alarm since the device is interactive again
+ cancelPendingAutoLockAlarms();
}
}
}
};
+ private void cancelPendingAutoLockAlarms() {
+ final AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+ if (alarmManager != null && mPrivateSpaceAutoLockTimer != null) {
+ alarmManager.cancel(mPrivateSpaceAutoLockTimer);
+ }
+ }
+
@VisibleForTesting
- void maybeScheduleMessageToAutoLockPrivateSpace() {
+ void maybeScheduleAlarmToAutoLockPrivateSpace() {
// No action needed if auto-lock on inactivity not selected
- int privateSpaceAutoLockPreference =
+ final int privateSpaceAutoLockPreference =
Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
@@ -636,26 +657,65 @@
}
int privateProfileUserId = getPrivateProfileUserId();
if (privateProfileUserId != UserHandle.USER_NULL) {
- scheduleMessageToAutoLockPrivateSpace(privateProfileUserId,
- PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN,
+ if (isQuietModeEnabled(privateProfileUserId)) {
+ Slogf.d(LOG_TAG, "Not scheduling auto-lock alarm for %d, "
+ + "quiet mode already enabled", privateProfileUserId);
+ return;
+ }
+ scheduleAlarmToAutoLockPrivateSpace(privateProfileUserId,
PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_TIMEOUT_MS);
}
}
@VisibleForTesting
- void scheduleMessageToAutoLockPrivateSpace(int userId, Object token,
- long delayInMillis) {
- Slog.i(LOG_TAG, "Scheduling auto-lock message");
- mHandler.postDelayed(() -> {
+ void scheduleAlarmToAutoLockPrivateSpace(int userId, long delayInMillis) {
+ final AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+ if (alarmManager == null) {
+ Slog.e(LOG_TAG, "AlarmManager not available, cannot schedule auto-lock alarm");
+ return;
+ }
+ initPrivateSpaceAutoLockTimer(userId);
+ final long alarmWindowStartTime = SystemClock.elapsedRealtime() + delayInMillis;
+ alarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ alarmWindowStartTime,
+ PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_ALARM_WINDOW_MS,
+ PRIVATE_SPACE_AUTO_LOCK_TIMER_TAG,
+ new HandlerExecutor(mHandler),
+ mPrivateSpaceAutoLockTimer);
+ }
+
+ private void initPrivateSpaceAutoLockTimer(int userId) {
+ cancelPendingAutoLockAlarms();
+ if (mPrivateSpaceAutoLockTimer == null
+ || mPrivateSpaceAutoLockTimer.getUserId() != userId) {
+ mPrivateSpaceAutoLockTimer = new PrivateSpaceAutoLockTimer(userId);
+ }
+ }
+
+ private class PrivateSpaceAutoLockTimer implements AlarmManager.OnAlarmListener {
+
+ private final int mUserId;
+
+ PrivateSpaceAutoLockTimer(int userId) {
+ mUserId = userId;
+ }
+
+ int getUserId() {
+ return mUserId;
+ }
+
+ @Override
+ public void onAlarm() {
final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
if (powerManager != null && !powerManager.isInteractive()) {
- Slog.i(LOG_TAG, "Auto-locking private space with user-id " + userId);
- setQuietModeEnabledAsync(userId, true,
+ Slog.i(LOG_TAG, "Auto-locking private space with user-id " + mUserId);
+ setQuietModeEnabledAsync(mUserId, true,
/* target */ null, mContext.getPackageName());
} else {
- Slog.i(LOG_TAG, "Device is interactive, skipping auto-lock");
+ Slog.i(LOG_TAG, "Device is interactive, skipping auto-lock for profile user "
+ + mUserId);
}
- }, token, delayInMillis);
+ }
}
@RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
@@ -701,7 +761,7 @@
// Unregister device inactivity broadcasts
if (mIsDeviceInactivityBroadcastReceiverRegistered) {
Slog.i(LOG_TAG, "Removing device inactivity broadcast receivers");
- mHandler.removeCallbacksAndMessages(PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN);
+ cancelPendingAutoLockAlarms();
mContext.unregisterReceiver(mDeviceInactivityBroadcastReceiver);
mIsDeviceInactivityBroadcastReceiverRegistered = false;
}
@@ -1076,6 +1136,10 @@
}
showHsumNotificationIfNeeded();
+
+ if (Flags.addUiForSoundsFromBackgroundUsers()) {
+ new BackgroundUserSoundNotifier(mContext);
+ }
}
private boolean isAutoLockingPrivateSpaceOnRestartsEnabled() {
@@ -5970,6 +6034,7 @@
@VisibleForTesting
void removeUserInfo(@UserIdInt int userId) {
synchronized (mUsersLock) {
+ UserManager.invalidateUserSerialNumberCache();
mUsers.remove(userId);
}
}
@@ -6395,6 +6460,7 @@
// Remove this user from the list
synchronized (mUsersLock) {
+ UserManager.invalidateUserSerialNumberCache();
mUsers.remove(userId);
mIsUserManaged.delete(userId);
}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 57ea233..4d07ab5 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -807,7 +807,7 @@
getDefaultSystemHandlerActivityPackage(pm,
SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
userId, MICROPHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
- NOTIFICATION_PERMISSIONS, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS);
+ NOTIFICATION_PERMISSIONS);
}
// Voice recognition
@@ -875,6 +875,12 @@
getDefaultSystemHandlerActivityPackage(pm, ACTION_TRACK, userId), userId,
SENSORS_PERMISSIONS);
}
+
+ // Allow voice search on wear
+ grantPermissionsToSystemPackage(pm,
+ getDefaultSystemHandlerActivityPackage(pm,
+ SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
+ userId, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS);
}
// Print Spooler
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index bf90a6c..0cda30f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2090,8 +2090,13 @@
"Home - Long Press");
switch (mLongPressOnHomeBehavior) {
case LONG_PRESS_HOME_ALL_APPS:
- logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
- launchAllAppsAction();
+ if (mHasFeatureLeanback) {
+ launchAllAppsAction();
+ logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
+ } else {
+ launchAllAppsViaA11y();
+ logKeyboardSystemsEvent(event, KeyboardLogEvent.ACCESSIBILITY_ALL_APPS);
+ }
break;
case LONG_PRESS_HOME_ASSIST:
logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_ASSISTANT);
@@ -3683,12 +3688,17 @@
}
break;
case KeyEvent.KEYCODE_ALL_APPS:
- if (!down) {
- mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
- Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
- msg.setAsynchronous(true);
- msg.sendToTarget();
- logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
+ if (firstDown) {
+ if (mHasFeatureLeanback) {
+ mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
+ Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
+ msg.setAsynchronous(true);
+ msg.sendToTarget();
+ logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
+ } else {
+ launchAllAppsViaA11y();
+ logKeyboardSystemsEvent(event, KeyboardLogEvent.ACCESSIBILITY_ALL_APPS);
+ }
}
return true;
case KeyEvent.KEYCODE_NOTIFICATION:
diff --git a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
index ff1d2e4..c6ef89d 100644
--- a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
+++ b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
@@ -16,6 +16,8 @@
package com.android.server.power.feature;
+import android.os.Build;
+import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Slog;
@@ -82,7 +84,7 @@
}
return mEnabled;
}
- mEnabled = mFlagFunction.get();
+ mEnabled = flagOrSystemProperty(mFlagFunction, mName);
if (DEBUG) {
Slog.d(TAG, mName + ": mEnabled. Flag value = " + mEnabled);
}
@@ -90,6 +92,15 @@
return mEnabled;
}
+ private boolean flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName) {
+ boolean flagValue = flagFunction.get();
+ if (Build.IS_ENG || Build.IS_USERDEBUG) {
+ return SystemProperties.getBoolean("persist.sys." + flagName + "-override",
+ flagValue);
+ }
+ return flagValue;
+ }
+
@Override
public String toString() {
// remove com.android.server.power.feature.flags. from the beginning of the name.
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index eabc979..1b7bf89 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -28,6 +28,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.usage.NetworkStatsManager;
@@ -1974,13 +1975,15 @@
private WifiManager mWifiManager;
private BluetoothPowerStatsCollector.BluetoothStatsRetriever mBluetoothStatsRetriever;
+ @SuppressLint("WifiManagerPotentialLeak")
void setContext(Context context) {
mPackageManager = context.getPackageManager();
mConsumedEnergyRetriever = new PowerStatsCollector.ConsumedEnergyRetrieverImpl(
LocalServices.getService(PowerStatsInternal.class));
mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);
- mTelephonyManager = context.getSystemService(TelephonyManager.class);
- mWifiManager = context.getSystemService(WifiManager.class);
+ mTelephonyManager =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mBluetoothStatsRetriever = new BluetoothStatsRetrieverImpl(
context.getSystemService(BluetoothManager.class));
}
@@ -11288,10 +11291,11 @@
mCpuPowerStatsCollector.addConsumer(this::recordPowerStats);
mMobileRadioPowerStatsCollector = new MobileRadioPowerStatsCollector(
- mPowerStatsCollectorInjector);
+ mPowerStatsCollectorInjector, this::onMobileRadioPowerStatsRetrieved);
mMobileRadioPowerStatsCollector.addConsumer(this::recordPowerStats);
- mWifiPowerStatsCollector = new WifiPowerStatsCollector(mPowerStatsCollectorInjector);
+ mWifiPowerStatsCollector = new WifiPowerStatsCollector(mPowerStatsCollectorInjector,
+ this::onWifiPowerStatsRetrieved);
mWifiPowerStatsCollector.addConsumer(this::recordPowerStats);
mBluetoothPowerStatsCollector = new BluetoothPowerStatsCollector(
@@ -12320,16 +12324,13 @@
/**
* Distribute WiFi energy info and network traffic to apps.
+ *
* @param info The energy information from the WiFi controller.
*/
@GuardedBy("this")
public void updateWifiState(@Nullable final WifiActivityEnergyInfo info,
final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs,
@NonNull NetworkStatsManager networkStatsManager) {
- if (mWifiPowerStatsCollector.isEnabled()) {
- return;
- }
-
if (DEBUG_ENERGY) {
synchronized (mWifiNetworkLock) {
Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces));
@@ -12347,7 +12348,20 @@
delta = null;
}
}
+ updateWifiBatteryStats(info, delta, consumedChargeUC, elapsedRealtimeMs, uptimeMs);
+ }
+ private void onWifiPowerStatsRetrieved(WifiActivityEnergyInfo wifiActivityEnergyInfo,
+ List<NetworkStatsDelta> networkStatsDeltas, long elapsedRealtimeMs, long uptimeMs) {
+ // Do not populate consumed energy, because energy attribution is done by
+ // WifiPowerStatsProcessor.
+ updateWifiBatteryStats(wifiActivityEnergyInfo, networkStatsDeltas, POWER_DATA_UNAVAILABLE,
+ elapsedRealtimeMs, uptimeMs);
+ }
+
+ private void updateWifiBatteryStats(WifiActivityEnergyInfo info,
+ List<NetworkStatsDelta> delta, long consumedChargeUC, long elapsedRealtimeMs,
+ long uptimeMs) {
synchronized (this) {
if (!mOnBatteryInternal || mIgnoreNextExternalStats) {
if (mIgnoreNextExternalStats) {
@@ -12711,9 +12725,6 @@
: mLastModemActivityInfo.getDelta(activityInfo);
mLastModemActivityInfo = activityInfo;
- // Add modem tx power to history.
- addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs);
-
// Grab a separate lock to acquire the network stats, which may do I/O.
List<NetworkStatsDelta> delta = null;
synchronized (mModemNetworkLock) {
@@ -12724,6 +12735,23 @@
}
}
+ updateCellularBatteryStats(deltaInfo, delta, consumedChargeUC, elapsedRealtimeMs, uptimeMs);
+ }
+
+ private void onMobileRadioPowerStatsRetrieved(ModemActivityInfo modemActivityInfo,
+ List<NetworkStatsDelta> networkStatsDeltas, long elapsedRealtimeMs, long uptimeMs) {
+ // Do not populate consumed energy, because energy attribution is done by
+ // MobileRadioPowerStatsProcessor.
+ updateCellularBatteryStats(modemActivityInfo, networkStatsDeltas, POWER_DATA_UNAVAILABLE,
+ elapsedRealtimeMs, uptimeMs);
+ }
+
+ private void updateCellularBatteryStats(@Nullable ModemActivityInfo deltaInfo,
+ @Nullable List<NetworkStatsDelta> delta, long consumedChargeUC, long elapsedRealtimeMs,
+ long uptimeMs) {
+ // Add modem tx power to history.
+ addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs);
+
synchronized (this) {
final long totalRadioDurationMs =
mMobileRadioActiveTimer.getTimeSinceMarkLocked(
@@ -13111,7 +13139,6 @@
final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq);
final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq);
-
ratStats.incrementRxDuration(freq, rxTimeMs);
if (isMobileRadioEnergyConsumerSupportedLocked()) {
// Accumulate the power cost of time spent receiving in a particular state.
@@ -15387,16 +15414,15 @@
/*@hide */
public WifiBatteryStats getWifiBatteryStats() {
final int which = STATS_SINCE_CHARGED;
- final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000;
+ final long rawRealTimeUs = mClock.elapsedRealtime() * 1000;
final ControllerActivityCounter counter = getWifiControllerActivity();
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
- final long totalControllerActivityTimeMs
- = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
- final long sleepTimeMs
- = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs);
+ final long totalControllerActivityTimeMs =
+ computeBatteryRealtime(mClock.elapsedRealtime() * 1000, which) / 1000;
+ final long sleepTimeMs = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs);
final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
final long monitoredRailChargeConsumedMaMs =
counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which);
diff --git a/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java
index 33ea563..c88e1b0 100644
--- a/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java
@@ -16,6 +16,7 @@
package com.android.server.power.stats;
+import android.annotation.Nullable;
import android.content.pm.PackageManager;
import android.hardware.power.stats.EnergyConsumerType;
import android.net.NetworkStats;
@@ -69,6 +70,13 @@
AccessNetworkConstants.AccessNetworkType.NGRAN
};
+ interface Observer {
+ void onMobileRadioPowerStatsRetrieved(
+ @Nullable ModemActivityInfo modemActivityDelta,
+ @Nullable List<BatteryStatsImpl.NetworkStatsDelta> networkStatsDeltas,
+ long elapsedRealtimeMs, long uptimeMs);
+ }
+
interface Injector {
Handler getHandler();
Clock getClock();
@@ -84,6 +92,7 @@
}
private final Injector mInjector;
+ private final Observer mObserver;
private MobileRadioPowerStatsLayout mLayout;
private boolean mIsInitialized;
@@ -105,13 +114,14 @@
private long mLastCallDuration;
private long mLastScanDuration;
- MobileRadioPowerStatsCollector(Injector injector) {
+ MobileRadioPowerStatsCollector(Injector injector, Observer observer) {
super(injector.getHandler(), injector.getPowerStatsCollectionThrottlePeriod(
BatteryConsumer.powerComponentIdToString(
BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)),
injector.getUidResolver(),
injector.getClock());
mInjector = injector;
+ mObserver = observer;
}
@Override
@@ -198,10 +208,8 @@
Arrays.fill(mPowerStats.stats, 0);
mPowerStats.uidStats.clear();
- collectModemActivityInfo();
-
- collectNetworkStats();
-
+ ModemActivityInfo modemActivityDelta = collectModemActivityInfo();
+ List<BatteryStatsImpl.NetworkStatsDelta> networkStatsDeltas = collectNetworkStats();
if (mEnergyConsumerIds.length != 0) {
collectEnergyConsumers();
}
@@ -210,12 +218,16 @@
setTimestamp(mClock.elapsedRealtime());
}
+ if (mObserver != null) {
+ mObserver.onMobileRadioPowerStatsRetrieved(modemActivityDelta,
+ networkStatsDeltas, mClock.elapsedRealtime(), mClock.uptimeMillis());
+ }
return mPowerStats;
}
- private void collectModemActivityInfo() {
+ private ModemActivityInfo collectModemActivityInfo() {
if (mTelephonyManager == null) {
- return;
+ return null;
}
CompletableFuture<ModemActivityInfo> immediateFuture = new CompletableFuture<>();
@@ -243,7 +255,7 @@
}
if (activityInfo == null) {
- return;
+ return null;
}
ModemActivityInfo deltaInfo = mLastModemActivityInfo == null
@@ -293,12 +305,13 @@
}
}
}
+ return deltaInfo;
}
- private void collectNetworkStats() {
+ private List<BatteryStatsImpl.NetworkStatsDelta> collectNetworkStats() {
NetworkStats networkStats = mNetworkStatsSupplier.get();
if (networkStats == null) {
- return;
+ return null;
}
List<BatteryStatsImpl.NetworkStatsDelta> delta =
@@ -330,6 +343,7 @@
mLayout.setUidTxPackets(stats, mLayout.getUidTxPackets(stats) + txPackets);
}
}
+ return delta;
}
private void collectEnergyConsumers() {
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
index 4bba649..549a97e 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
@@ -154,8 +154,11 @@
batteryUsageStatsBuilder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
if (descriptor.powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
- deviceScope.addConsumedPowerForCustomComponent(descriptor.powerComponentId,
- totalPower[0]);
+ if (batteryUsageStatsBuilder.isSupportedCustomPowerComponent(
+ descriptor.powerComponentId)) {
+ deviceScope.addConsumedPowerForCustomComponent(descriptor.powerComponentId,
+ totalPower[0]);
+ }
} else {
deviceScope.addConsumedPower(descriptor.powerComponentId,
totalPower[0], BatteryConsumer.POWER_MODEL_UNDEFINED);
diff --git a/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
index bd04199..6d519ee 100644
--- a/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
@@ -43,6 +43,12 @@
private static final long ENERGY_UNSPECIFIED = -1;
+ interface Observer {
+ void onWifiPowerStatsRetrieved(WifiActivityEnergyInfo info,
+ List<BatteryStatsImpl.NetworkStatsDelta> delta, long elapsedRealtimeMs,
+ long uptimeMs);
+ }
+
interface WifiStatsRetriever {
interface Callback {
void onWifiScanTime(int uid, long scanTimeMs, long batchScanTimeMs);
@@ -66,6 +72,7 @@
}
private final Injector mInjector;
+ private final Observer mObserver;
private WifiPowerStatsLayout mLayout;
private boolean mIsInitialized;
@@ -93,12 +100,13 @@
private final SparseArray<WifiScanTimes> mLastScanTimes = new SparseArray<>();
private long mLastWifiActiveDuration;
- WifiPowerStatsCollector(Injector injector) {
+ WifiPowerStatsCollector(Injector injector, Observer observer) {
super(injector.getHandler(), injector.getPowerStatsCollectionThrottlePeriod(
BatteryConsumer.powerComponentIdToString(
BatteryConsumer.POWER_COMPONENT_WIFI)),
injector.getUidResolver(), injector.getClock());
mInjector = injector;
+ mObserver = observer;
}
@Override
@@ -160,22 +168,27 @@
return null;
}
+ WifiActivityEnergyInfo activityInfo = null;
if (mPowerReportingSupported) {
- collectWifiActivityInfo();
+ activityInfo = collectWifiActivityInfo();
} else {
collectWifiActivityStats();
}
- collectNetworkStats();
+ List<BatteryStatsImpl.NetworkStatsDelta> networkStatsDeltas = collectNetworkStats();
collectWifiScanTime();
if (mEnergyConsumerIds.length != 0) {
collectEnergyConsumers();
}
+ if (mObserver != null) {
+ mObserver.onWifiPowerStatsRetrieved(activityInfo, networkStatsDeltas,
+ mClock.elapsedRealtime(), mClock.uptimeMillis());
+ }
return mPowerStats;
}
- private void collectWifiActivityInfo() {
+ private WifiActivityEnergyInfo collectWifiActivityInfo() {
CompletableFuture<WifiActivityEnergyInfo> immediateFuture = new CompletableFuture<>();
mWifiManager.getWifiActivityEnergyInfoAsync(Runnable::run,
immediateFuture::complete);
@@ -190,7 +203,7 @@
}
if (activityInfo == null) {
- return;
+ return null;
}
long rxDuration = activityInfo.getControllerRxDurationMillis()
@@ -210,6 +223,9 @@
mPowerStats.durationMs = rxDuration + txDuration + scanDuration + idleDuration;
mLastWifiActivityInfo = activityInfo;
+
+ return new WifiActivityEnergyInfo(activityInfo.getTimeSinceBootMillis(),
+ activityInfo.getStackState(), txDuration, rxDuration, scanDuration, idleDuration);
}
private void collectWifiActivityStats() {
@@ -219,12 +235,12 @@
mPowerStats.durationMs = duration;
}
- private void collectNetworkStats() {
+ private List<BatteryStatsImpl.NetworkStatsDelta> collectNetworkStats() {
mPowerStats.uidStats.clear();
NetworkStats networkStats = mNetworkStatsSupplier.get();
if (networkStats == null) {
- return;
+ return null;
}
List<BatteryStatsImpl.NetworkStatsDelta> delta =
@@ -256,6 +272,7 @@
mLayout.setUidTxPackets(stats, mLayout.getUidTxPackets(stats) + txPackets);
}
}
+ return delta;
}
private void collectWifiScanTime() {
diff --git a/services/core/java/com/android/server/stats/pull/BatteryHealthUtility.java b/services/core/java/com/android/server/stats/pull/BatteryHealthUtility.java
new file mode 100644
index 0000000..e0768fe
--- /dev/null
+++ b/services/core/java/com/android/server/stats/pull/BatteryHealthUtility.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2024 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.stats.pull;
+
+import android.util.StatsEvent;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+/**
+ * Utility class to redact Battery Health data from HealthServiceWrapper
+ *
+ * @hide
+ */
+public abstract class BatteryHealthUtility {
+ /**
+ * Create a StatsEvent corresponding to the Battery Health data, the fields
+ * of which are redacted to preserve users' privacy.
+ * The redaction consists in truncating the timestamps to the Monday of the
+ * corresponding week, and reducing the battery serial into the last byte
+ * of its MD5.
+ */
+ public static StatsEvent buildStatsEvent(int atomTag,
+ android.hardware.health.BatteryHealthData data, int chargeStatus, int chargePolicy)
+ throws NoSuchAlgorithmException {
+ int manufacturingDate = secondsToWeekYYYYMMDD(data.batteryManufacturingDateSeconds);
+ int firstUsageDate = secondsToWeekYYYYMMDD(data.batteryFirstUsageSeconds);
+ long stateOfHealth = data.batteryStateOfHealth;
+ int partStatus = data.batteryPartStatus;
+ int serialHashTruncated = stringToIntHash(data.batterySerialNumber) & 0xFF; // Last byte
+
+ return FrameworkStatsLog.buildStatsEvent(atomTag, manufacturingDate, firstUsageDate,
+ (int) stateOfHealth, serialHashTruncated, partStatus, chargeStatus, chargePolicy);
+ }
+
+ private static int secondsToWeekYYYYMMDD(long seconds) {
+ Calendar calendar = Calendar.getInstance();
+ long millis = seconds * 1000L;
+
+ calendar.setTimeInMillis(millis);
+
+ // Truncate all date information, up to week, which is rounded to
+ // MONDAY
+ calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.US);
+
+ String formattedDate = sdf.format(calendar.getTime());
+
+ return Integer.parseInt(formattedDate);
+ }
+
+ private static int stringToIntHash(String data) throws NoSuchAlgorithmException {
+ if (data == null || data.isEmpty()) {
+ return 0;
+ }
+
+ MessageDigest digest = MessageDigest.getInstance("MD5");
+ byte[] hashBytes = digest.digest(data.getBytes());
+
+ // Convert to integer (simplest way, but potential for loss of information)
+ BigInteger bigInt = new BigInteger(1, hashBytes);
+ return bigInt.intValue();
+ }
+}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index c1b825b..0041d39 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -119,6 +119,8 @@
import android.net.NetworkTemplate;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.os.BatteryProperty;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.BatteryStatsManager;
@@ -243,6 +245,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
@@ -769,6 +772,7 @@
case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
case FrameworkStatsLog.BATTERY_VOLTAGE:
case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
+ case FrameworkStatsLog.BATTERY_HEALTH:
synchronized (mHealthHalLock) {
return pullHealthHalLocked(atomTag, data);
}
@@ -999,6 +1003,7 @@
registerFullBatteryCapacity();
registerBatteryVoltage();
registerBatteryCycleCount();
+ registerBatteryHealth();
registerSettingsStats();
registerInstalledIncrementalPackages();
registerKeystoreStorageStats();
@@ -4365,7 +4370,15 @@
);
}
- int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) {
+ private void registerBatteryHealth() {
+ int tagId = FrameworkStatsLog.BATTERY_HEALTH;
+ mStatsManager.setPullAtomCallback(tagId,
+ null, // use default PullAtomMetadata values
+ DIRECT_EXECUTOR, mStatsCallbackImpl);
+ }
+
+ @GuardedBy("mHealthHalLock")
+ private int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) {
if (mHealthService == null) {
return StatsManager.PULL_SKIP;
}
@@ -4396,6 +4409,44 @@
case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
pulledValue = healthInfo.batteryCycleCount;
break;
+ case FrameworkStatsLog.BATTERY_HEALTH:
+ android.hardware.health.BatteryHealthData bhd;
+ try {
+ bhd = mHealthService.getBatteryHealthData();
+ } catch (RemoteException | IllegalStateException e) {
+ return StatsManager.PULL_SKIP;
+ }
+ if (bhd == null) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ StatsEvent batteryHealthEvent;
+ try {
+ BatteryProperty chargeStatusProperty = new BatteryProperty();
+ BatteryProperty chargePolicyProperty = new BatteryProperty();
+
+ if (0 > mHealthService.getProperty(
+ BatteryManager.BATTERY_PROPERTY_STATUS, chargeStatusProperty)) {
+ return StatsManager.PULL_SKIP;
+ }
+ if (0 > mHealthService.getProperty(
+ BatteryManager.BATTERY_PROPERTY_CHARGING_POLICY,
+ chargePolicyProperty)) {
+ return StatsManager.PULL_SKIP;
+ }
+ int chargeStatus = (int) chargeStatusProperty.getLong();
+ int chargePolicy = (int) chargePolicyProperty.getLong();
+ batteryHealthEvent = BatteryHealthUtility.buildStatsEvent(
+ atomTag, bhd, chargeStatus, chargePolicy);
+ pulledData.add(batteryHealthEvent);
+
+ return StatsManager.PULL_SUCCESS;
+ } catch (RemoteException | IllegalStateException e) {
+ Slog.e(TAG, "Failed to add pulled data", e);
+ } catch (NoSuchAlgorithmException e) {
+ Slog.e(TAG, "Could not find message digest algorithm", e);
+ }
+ return StatsManager.PULL_SKIP;
default:
return StatsManager.PULL_SKIP;
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e0a8226..6721893 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -341,10 +341,16 @@
}, UserHandle.ALL, intentFilter, null, null);
}
+ private static boolean hasAlwaysBoundPermission(PackageManager pm, ComponentName component) {
+ return pm.checkPermission(android.Manifest.permission.ALWAYS_BOUND_TV_INPUT,
+ component.getPackageName()) == PackageManager.PERMISSION_GRANTED;
+ }
+
private static boolean hasHardwarePermission(PackageManager pm, ComponentName component) {
return pm.checkPermission(android.Manifest.permission.TV_INPUT_HARDWARE,
component.getPackageName()) == PackageManager.PERMISSION_GRANTED;
}
+
@GuardedBy("mLock")
private void buildTvInputListLocked(int userId, String[] updatedPackages) {
UserState userState = getOrCreateUserStateLocked(userId);
@@ -3526,7 +3532,7 @@
continue;
}
ComponentName component = new ComponentName(si.packageName, si.name);
- if (hasHardwarePermission(pm, component)) {
+ if (!hasAlwaysBoundPermission(pm, component) && hasHardwarePermission(pm, component)) {
updateServiceConnectionLocked(component, userId);
}
}
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index 34c90f1..edd2fa9 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -2124,7 +2124,7 @@
@Override
public void setTeletextAppEnabled(IBinder sessionToken, boolean enable, int userId) {
if (DEBUG) {
- Slogf.d(TAG, "setTeletextAppEnabled(enable=%d)", enable);
+ Slogf.d(TAG, "setTeletextAppEnabled(enable=%b)", enable);
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index b846947..72c7be3 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -101,6 +101,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
@@ -2209,8 +2210,12 @@
public ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId,
IWallpaperManagerCallback cb, final int which, Bundle outParams, int wallpaperUserId,
boolean getCropped) {
- final boolean hasPrivilege = hasPermission(READ_WALLPAPER_INTERNAL);
- if (!hasPrivilege) checkPermission(MANAGE_EXTERNAL_STORAGE);
+ final boolean hasPrivilege = hasPermission(READ_WALLPAPER_INTERNAL)
+ || hasPermission(MANAGE_EXTERNAL_STORAGE);
+ if (!hasPrivilege) {
+ mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
+ Binder.getCallingPid(), Binder.getCallingUid(), callingPkg, callingFeatureId);
+ }
wallpaperUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), wallpaperUserId, false, true, "getWallpaper", null);
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 0e0b78f..2d8aa3f 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -382,12 +382,6 @@
}
return null;
}
- if (activity.hasCommittedReparentToAnimationLeash()) {
- if (DEBUG_SCREENSHOT) {
- Slog.w(TAG_WM, "Failed to take screenshot. App is animating " + activity);
- }
- return null;
- }
final WindowState mainWindow = activity.findMainWindow();
if (mainWindow == null) {
Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + source);
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 3e177c9..a8dcaa8 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -102,7 +102,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AssistUtils;
import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.Watchdog;
import com.android.server.pm.KnownPackages;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 21155bb..484481b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -93,6 +93,7 @@
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN;
import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
@@ -385,7 +386,7 @@
import com.android.internal.os.TimeoutRecord;
import com.android.internal.os.TransferPipe;
import com.android.internal.policy.AttributeCache;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -4577,9 +4578,6 @@
if (!delayed) {
updateReportedVisibilityLocked();
}
-
- // Reset the last saved PiP snap fraction on removal.
- mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
mDisplayContent.onRunningActivityChanged();
mRemovingFromDisplay = false;
}
@@ -6743,8 +6741,6 @@
if (task.mLastRecentsAnimationTransaction != null) {
task.clearLastRecentsAnimationTransaction(true /* forceRemoveOverlay */);
}
- // Reset the last saved PiP snap fraction on app stop.
- mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
if (isClientVisible()) {
// Though this is usually unlikely to happen, still make sure the client is invisible.
setClientVisible(false);
@@ -6752,6 +6748,13 @@
destroySurfaces();
// Remove any starting window that was added for this app if they are still around.
removeStartingWindow();
+ // This is unlikely to happen because the sequence of lifecycle should invoke
+ // finishRelaunching before being stopped. Reset the potential unpaired count in case
+ // the binder transaction of relaunch is failed, so the transition won't be blocked.
+ if (mPendingRelaunchCount > 0) {
+ Slog.i(TAG, "Clear pending relaunch count on stopped " + this);
+ clearRelaunching();
+ }
if (finishing) {
abortAndClearOptionsAnimation();
@@ -8183,8 +8186,7 @@
}
void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
- if (mAppCompatController.getAppCompatCapability()
- .getAppCompatOrientationCapability()
+ if (mAppCompatController.getAppCompatOrientationOverrides()
.shouldIgnoreRequestedOrientation(requestedOrientation)) {
return;
}
@@ -8563,7 +8565,7 @@
final int parentWindowingMode =
newParentConfiguration.windowConfiguration.getWindowingMode();
final boolean isInCameraCompatFreeform = parentWindowingMode == WINDOWING_MODE_FREEFORM
- && mLetterboxUiController.getFreeformCameraCompatMode()
+ && mAppCompatController.getAppCompatCameraOverrides().getFreeformCameraCompatMode()
!= CAMERA_COMPAT_FREEFORM_NONE;
// Bubble activities should always fill their parent and should not be letterboxed.
@@ -9891,7 +9893,8 @@
return mLetterboxUiController.getUserMinAspectRatio();
}
if (!mLetterboxUiController.shouldOverrideMinAspectRatio()
- && !mLetterboxUiController.shouldOverrideMinAspectRatioForCamera()) {
+ && !mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera()) {
return info.getMinAspectRatio();
}
if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY)
@@ -9921,6 +9924,11 @@
return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE,
info.getMinAspectRatio());
}
+
+ if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_SMALL)) {
+ return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE,
+ info.getMinAspectRatio());
+ }
return info.getMinAspectRatio();
}
@@ -10813,15 +10821,18 @@
proto.write(OVERRIDE_ORIENTATION, getOverrideOrientation());
proto.write(SHOULD_SEND_COMPAT_FAKE_FOCUS, shouldSendCompatFakeFocus());
proto.write(SHOULD_FORCE_ROTATE_FOR_CAMERA_COMPAT,
- mLetterboxUiController.shouldForceRotateForCameraCompat());
+ mAppCompatController.getAppCompatCameraOverrides()
+ .shouldForceRotateForCameraCompat());
proto.write(SHOULD_REFRESH_ACTIVITY_FOR_CAMERA_COMPAT,
- mLetterboxUiController.shouldRefreshActivityForCameraCompat());
+ mAppCompatController.getAppCompatCameraOverrides()
+ .shouldRefreshActivityForCameraCompat());
proto.write(SHOULD_REFRESH_ACTIVITY_VIA_PAUSE_FOR_CAMERA_COMPAT,
- mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat());
+ mAppCompatController.getAppCompatCameraOverrides()
+ .shouldRefreshActivityViaPauseForCameraCompat());
proto.write(SHOULD_OVERRIDE_MIN_ASPECT_RATIO,
mLetterboxUiController.shouldOverrideMinAspectRatio());
proto.write(SHOULD_IGNORE_ORIENTATION_REQUEST_LOOP,
- mAppCompatController.getAppCompatCapability().getAppCompatOrientationCapability()
+ mAppCompatController.getAppCompatOrientationOverrides()
.shouldIgnoreOrientationRequestLoop());
proto.write(SHOULD_OVERRIDE_FORCE_RESIZE_APP,
mLetterboxUiController.shouldOverrideForceResizeApp());
diff --git a/services/core/java/com/android/server/wm/ActivityRefresher.java b/services/core/java/com/android/server/wm/ActivityRefresher.java
index 23a9708..0c32dfc 100644
--- a/services/core/java/com/android/server/wm/ActivityRefresher.java
+++ b/services/core/java/com/android/server/wm/ActivityRefresher.java
@@ -27,7 +27,7 @@
import android.os.Handler;
import android.os.RemoteException;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
@@ -77,10 +77,10 @@
final boolean cycleThroughStop =
mWmService.mLetterboxConfiguration
.isCameraCompatRefreshCycleThroughStopEnabled()
- && !activity.mLetterboxUiController
- .shouldRefreshActivityViaPauseForCameraCompat();
+ && !activity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldRefreshActivityViaPauseForCameraCompat();
- activity.mLetterboxUiController.setIsRefreshRequested(true);
+ activity.mAppCompatController.getAppCompatCameraOverrides().setIsRefreshRequested(true);
ProtoLog.v(WM_DEBUG_STATES,
"Refreshing activity for freeform camera compatibility treatment, "
+ "activityRecord=%s", activity);
@@ -97,24 +97,26 @@
}
}, REFRESH_CALLBACK_TIMEOUT_MS);
} catch (RemoteException e) {
- activity.mLetterboxUiController.setIsRefreshRequested(false);
+ activity.mAppCompatController.getAppCompatCameraOverrides()
+ .setIsRefreshRequested(false);
}
}
boolean isActivityRefreshing(@NonNull ActivityRecord activity) {
- return activity.mLetterboxUiController.isRefreshRequested();
+ return activity.mAppCompatController.getAppCompatCameraOverrides().isRefreshRequested();
}
void onActivityRefreshed(@NonNull ActivityRecord activity) {
// TODO(b/333060789): can we tell that refresh did not happen by observing the activity
// state?
- activity.mLetterboxUiController.setIsRefreshRequested(false);
+ activity.mAppCompatController.getAppCompatCameraOverrides().setIsRefreshRequested(false);
}
private boolean shouldRefreshActivity(@NonNull ActivityRecord activity,
@NonNull Configuration newConfig, @NonNull Configuration lastReportedConfig) {
return mWmService.mLetterboxConfiguration.isCameraCompatRefreshEnabled()
- && activity.mLetterboxUiController.shouldRefreshActivityForCameraCompat()
+ && activity.mAppCompatController.getAppCompatOverrides()
+ .getAppCompatCameraOverrides().shouldRefreshActivityForCameraCompat()
&& ArrayUtils.find(mEvaluators.toArray(), evaluator ->
((Evaluator) evaluator)
.shouldRefreshActivity(activity, newConfig, lastReportedConfig)) != null;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 717c399..5bfe9d7 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -127,7 +127,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
import com.android.server.pm.PackageArchiver;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 2109f5d..ded205e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -260,7 +260,7 @@
import com.android.internal.os.TransferPipe;
import com.android.internal.policy.AttributeCache;
import com.android.internal.policy.KeyguardDismissCallback;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
@@ -6192,11 +6192,14 @@
synchronized (mGlobalLockWithoutBoost) {
final WindowProcessController proc = mProcessNames.remove(name, uid);
if (proc != null && !mStartingProcessActivities.isEmpty()) {
- for (int i = mStartingProcessActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord r = mStartingProcessActivities.get(i);
+ // Use a copy in case finishIfPossible changes the list indirectly.
+ final ArrayList<ActivityRecord> activities =
+ new ArrayList<>(mStartingProcessActivities);
+ for (int i = activities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = activities.get(i);
if (uid == r.info.applicationInfo.uid && name.equals(r.processName)) {
Slog.w(TAG, proc + " is removed with pending start " + r);
- mStartingProcessActivities.remove(i);
+ mStartingProcessActivities.remove(r);
// If visible, finish it to avoid getting stuck on screen.
if (r.isVisibleRequested()) {
r.finishIfPossible("starting-proc-removed", false /* oomAdj */);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index cd5576f..d65a106 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -148,7 +148,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.ReferrerIntent;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 0013c5c..80671ef 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -345,7 +345,7 @@
null /* processCpuTracker */, null /* lastPids */,
CompletableFuture.completedFuture(nativePids),
null /* logExceptionCreatingFile */, "Pre-dump", criticalEvents,
- Runnable::run, null/* AnrLatencyTracker */);
+ null /* extraHeaders */, Runnable::run, null/* AnrLatencyTracker */);
if (tracesFile != null) {
tracesFile.renameTo(
new File(tracesFile.getParent(), tracesFile.getName() + "_pre"));
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
new file mode 100644
index 0000000..c0e5005
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2024 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.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
+import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.NonNull;
+import android.app.CameraCompatTaskInfo.FreeformCameraCompatMode;
+
+import com.android.server.wm.utils.OptPropFactory;
+import com.android.window.flags.Flags;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Encapsulates app compat configurations and overrides related to camera.
+ */
+class AppCompatCameraOverrides {
+
+ private static final String TAG = TAG_WITH_CLASS_NAME
+ ? "AppCompatCameraOverrides" : TAG_ATM;
+
+ @NonNull
+ private final ActivityRecord mActivityRecord;
+ @NonNull
+ private final AppCompatCameraOverridesState mAppCompatCameraOverridesState;
+ @NonNull
+ private final LetterboxConfiguration mLetterboxConfiguration;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mCameraCompatAllowRefreshOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mCameraCompatEnableRefreshViaPauseOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mCameraCompatAllowForceRotationOptProp;
+
+ AppCompatCameraOverrides(@NonNull ActivityRecord activityRecord,
+ @NonNull LetterboxConfiguration letterboxConfiguration,
+ @NonNull OptPropFactory optPropBuilder) {
+ mActivityRecord = activityRecord;
+ mLetterboxConfiguration = letterboxConfiguration;
+ mAppCompatCameraOverridesState = new AppCompatCameraOverridesState();
+ mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
+ final BooleanSupplier isCameraCompatTreatmentEnabled = AppCompatUtils.asLazy(
+ mLetterboxConfiguration::isCameraCompatTreatmentEnabled);
+ mCameraCompatAllowRefreshOptProp = optPropBuilder.create(
+ PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH,
+ isCameraCompatTreatmentEnabled);
+ mCameraCompatEnableRefreshViaPauseOptProp = optPropBuilder.create(
+ PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE,
+ isCameraCompatTreatmentEnabled);
+ mCameraCompatAllowForceRotationOptProp = optPropBuilder.create(
+ PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION,
+ isCameraCompatTreatmentEnabled);
+ }
+
+ /**
+ * Whether we should apply the min aspect ratio per-app override only when an app is connected
+ * to the camera.
+ * When this override is applied the min aspect ratio given in the app's manifest will be
+ * overridden to the largest enabled aspect ratio treatment unless the app's manifest value
+ * is higher. The treatment will also apply if no value is provided in the manifest.
+ *
+ * <p>This method returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>Opt-out component property isn't enabled
+ * <li>Per-app override is enabled
+ * </ul>
+ */
+ boolean shouldOverrideMinAspectRatioForCamera() {
+ return mActivityRecord.isCameraActive()
+ && mAllowMinAspectRatioOverrideOptProp
+ .shouldEnableWithOptInOverrideAndOptOutProperty(
+ isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA));
+ }
+
+ /**
+ * Whether activity is eligible for activity "refresh" after camera compat force rotation
+ * treatment. See {@link DisplayRotationCompatPolicy} for context.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the camera compat treatment is enabled.
+ * <li>Activity isn't opted out by the device manufacturer with override or by the app
+ * developers with the component property.
+ * </ul>
+ */
+ boolean shouldRefreshActivityForCameraCompat() {
+ return mCameraCompatAllowRefreshOptProp.shouldEnableWithOptOutOverrideAndProperty(
+ isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH));
+ }
+
+ /**
+ * Whether activity should be "refreshed" after the camera compat force rotation treatment
+ * using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
+ * -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the camera compat treatment is enabled.
+ * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
+ * component property by the app developers.
+ * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
+ * manufacturer with override / by the app developers with the component property.
+ * </ul>
+ */
+ boolean shouldRefreshActivityViaPauseForCameraCompat() {
+ return mCameraCompatEnableRefreshViaPauseOptProp.shouldEnableWithOverrideAndProperty(
+ isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE));
+ }
+
+ /**
+ * Whether activity is eligible for camera compat force rotation treatment. See {@link
+ * DisplayRotationCompatPolicy} for context.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the camera compat treatment is enabled.
+ * <li>Activity isn't opted out by the device manufacturer with override or by the app
+ * developers with the component property.
+ * </ul>
+ */
+ boolean shouldForceRotateForCameraCompat() {
+ return mCameraCompatAllowForceRotationOptProp.shouldEnableWithOptOutOverrideAndProperty(
+ isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION));
+ }
+
+ /**
+ * Whether activity is eligible for camera compatibility free-form treatment.
+ *
+ * <p>The treatment is applied to a fixed-orientation camera activity in free-form windowing
+ * mode. The treatment letterboxes or pillarboxes the activity to the expected orientation and
+ * provides changes to the camera and display orientation signals to match those expected on a
+ * portrait device in that orientation (for example, on a standard phone).
+ *
+ * <p>The treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Property gating the camera compatibility free-form treatment is enabled.
+ * <li>Activity isn't opted out by the device manufacturer with override.
+ * </ul>
+ */
+ boolean shouldApplyFreeformTreatmentForCameraCompat() {
+ return Flags.cameraCompatForFreeform() && !isCompatChangeEnabled(
+ OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT);
+ }
+
+ /**
+ * @return {@code true} if the configuration needs to be recomputed after a camera state update.
+ */
+ boolean shouldRecomputeConfigurationForCameraCompat() {
+ return isOverrideOrientationOnlyForCameraEnabled()
+ || isCameraCompatSplitScreenAspectRatioAllowed()
+ || shouldOverrideMinAspectRatioForCamera();
+ }
+
+ boolean isOverrideOrientationOnlyForCameraEnabled() {
+ return isCompatChangeEnabled(OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA);
+ }
+
+ /**
+ * Whether activity "refresh" was requested but not finished in {@link #activityResumedLocked}.
+ */
+ boolean isRefreshRequested() {
+ return mAppCompatCameraOverridesState.mIsRefreshRequested;
+ }
+
+ /**
+ * @param isRequested Whether activity "refresh" was requested but not finished
+ * in {@link #activityResumedLocked}.
+ */
+ void setIsRefreshRequested(boolean isRequested) {
+ mAppCompatCameraOverridesState.mIsRefreshRequested = isRequested;
+ }
+
+ /**
+ * Whether we use split screen aspect ratio for the activity when camera compat treatment
+ * is active because the corresponding config is enabled and activity supports resizing.
+ */
+ boolean isCameraCompatSplitScreenAspectRatioAllowed() {
+ return mLetterboxConfiguration.isCameraCompatSplitScreenAspectRatioEnabled()
+ && !mActivityRecord.shouldCreateCompatDisplayInsets();
+ }
+
+ @FreeformCameraCompatMode
+ int getFreeformCameraCompatMode() {
+ return mAppCompatCameraOverridesState.mFreeformCameraCompatMode;
+ }
+
+ void setFreeformCameraCompatMode(@FreeformCameraCompatMode int freeformCameraCompatMode) {
+ mAppCompatCameraOverridesState.mFreeformCameraCompatMode = freeformCameraCompatMode;
+ }
+
+ private boolean isCompatChangeEnabled(long overrideChangeId) {
+ return mActivityRecord.info.isChangeEnabled(overrideChangeId);
+ }
+
+ static class AppCompatCameraOverridesState {
+ // Whether activity "refresh" was requested but not finished in
+ // ActivityRecord#activityResumedLocked following the camera compat force rotation in
+ // DisplayRotationCompatPolicy.
+ private boolean mIsRefreshRequested;
+
+ @FreeformCameraCompatMode
+ private int mFreeformCameraCompatMode = CAMERA_COMPAT_FREEFORM_NONE;
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
new file mode 100644
index 0000000..ee523a2
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 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.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.NonNull;
+
+/**
+ * Encapsulate the app compat logic related to camera.
+ */
+class AppCompatCameraPolicy {
+
+ private static final String TAG = TAG_WITH_CLASS_NAME
+ ? "AppCompatCameraPolicy" : TAG_ATM;
+
+ @NonNull
+ private final ActivityRecord mActivityRecord;
+
+ @NonNull
+ private final AppCompatCameraOverrides mAppCompatCameraOverrides;
+
+ AppCompatCameraPolicy(@NonNull ActivityRecord activityRecord,
+ @NonNull AppCompatCameraOverrides appCompatCameraOverrides) {
+ mActivityRecord = activityRecord;
+ mAppCompatCameraOverrides = appCompatCameraOverrides;
+ }
+
+ void recomputeConfigurationForCameraCompatIfNeeded() {
+ if (mAppCompatCameraOverrides.shouldRecomputeConfigurationForCameraCompat()) {
+ mActivityRecord.recomputeConfiguration();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatCapability.java b/services/core/java/com/android/server/wm/AppCompatCapability.java
deleted file mode 100644
index d4379e48..0000000
--- a/services/core/java/com/android/server/wm/AppCompatCapability.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2024 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.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
-import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
-import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
-import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
-import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
-
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-
-import android.annotation.NonNull;
-import android.content.pm.PackageManager;
-
-import com.android.server.wm.utils.OptPropFactory;
-import com.android.window.flags.Flags;
-
-import java.util.function.BooleanSupplier;
-
-/**
- * Encapsulate logic related to operations guarded by an app override.
- */
-public class AppCompatCapability {
-
- private static final String TAG = TAG_WITH_CLASS_NAME ? "AppCompatCapability" : TAG_ATM;
-
- @NonNull
- private final LetterboxConfiguration mLetterboxConfiguration;
-
- @NonNull
- private final ActivityRecord mActivityRecord;
-
- // Corresponds to OVERRIDE_ANY_ORIENTATION_TO_USER
- private final boolean mIsSystemOverrideToFullscreenEnabled;
- // Corresponds to OVERRIDE_RESPECT_REQUESTED_ORIENTATION
- private final boolean mIsOverrideRespectRequestedOrientationEnabled;
- // Corresponds to OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA
- private final boolean mIsOverrideOrientationOnlyForCameraEnabled;
-
- @NonNull
- private final OptPropFactory.OptProp mFakeFocusOptProp;
- @NonNull
- private final OptPropFactory.OptProp mCameraCompatAllowForceRotationOptProp;
- @NonNull
- private final OptPropFactory.OptProp mCameraCompatAllowRefreshOptProp;
- @NonNull
- private final OptPropFactory.OptProp mCameraCompatEnableRefreshViaPauseOptProp;
- @NonNull
- private final OptPropFactory.OptProp mAllowOrientationOverrideOptProp;
- @NonNull
- private final OptPropFactory.OptProp mAllowDisplayOrientationOverrideOptProp;
- @NonNull
- private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp;
- @NonNull
- private final OptPropFactory.OptProp mAllowForceResizeOverrideOptProp;
- @NonNull
- private final OptPropFactory.OptProp mAllowUserAspectRatioOverrideOptProp;
- @NonNull
- private final OptPropFactory.OptProp mAllowUserAspectRatioFullscreenOverrideOptProp;
-
- private final AppCompatOrientationCapability mAppCompatOrientationCapability;
-
- AppCompatCapability(@NonNull WindowManagerService wmService,
- @NonNull ActivityRecord activityRecord,
- @NonNull LetterboxConfiguration letterboxConfiguration) {
- mLetterboxConfiguration = letterboxConfiguration;
- mActivityRecord = activityRecord;
- final PackageManager packageManager = wmService.mContext.getPackageManager();
-
- final OptPropFactory optPropBuilder = new OptPropFactory(packageManager,
- activityRecord.packageName);
-
- mAppCompatOrientationCapability =
- new AppCompatOrientationCapability(optPropBuilder, mLetterboxConfiguration,
- mActivityRecord);
-
- mFakeFocusOptProp = optPropBuilder.create(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS,
- mLetterboxConfiguration::isCompatFakeFocusEnabled);
-
- final BooleanSupplier isCameraCompatTreatmentEnabled = asLazy(
- mLetterboxConfiguration::isCameraCompatTreatmentEnabled);
- mCameraCompatAllowForceRotationOptProp = optPropBuilder.create(
- PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION,
- isCameraCompatTreatmentEnabled);
- mCameraCompatAllowRefreshOptProp = optPropBuilder.create(
- PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH,
- isCameraCompatTreatmentEnabled);
- mCameraCompatEnableRefreshViaPauseOptProp = optPropBuilder.create(
- PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE,
- isCameraCompatTreatmentEnabled);
-
- mAllowOrientationOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
-
- mAllowDisplayOrientationOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE,
- () -> mActivityRecord.mDisplayContent != null
- && mActivityRecord.getTask() != null
- && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest()
- && !mActivityRecord.getTask().inMultiWindowMode()
- && mActivityRecord.mDisplayContent.getNaturalOrientation()
- == ORIENTATION_LANDSCAPE
- );
-
- mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
- mAllowForceResizeOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES);
- mAllowUserAspectRatioOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE,
- mLetterboxConfiguration::isUserAppAspectRatioSettingsEnabled);
- mAllowUserAspectRatioFullscreenOverrideOptProp = optPropBuilder.create(
- PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
- mLetterboxConfiguration::isUserAppAspectRatioFullscreenEnabled);
-
- mIsSystemOverrideToFullscreenEnabled =
- isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION_TO_USER);
- mIsOverrideRespectRequestedOrientationEnabled =
- isCompatChangeEnabled(OVERRIDE_RESPECT_REQUESTED_ORIENTATION);
- mIsOverrideOrientationOnlyForCameraEnabled =
- isCompatChangeEnabled(OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA);
- }
-
- /**
- * @return {@code true} if the App Compat Camera Policy is active for the current activity.
- */
- boolean isCameraCompatTreatmentActive() {
- final DisplayContent displayContent = mActivityRecord.mDisplayContent;
- if (displayContent == null) {
- return false;
- }
- return displayContent.mDisplayRotationCompatPolicy != null
- && displayContent.mDisplayRotationCompatPolicy
- .isTreatmentEnabledForActivity(mActivityRecord);
- }
-
- @NonNull
- AppCompatOrientationCapability getAppCompatOrientationCapability() {
- return mAppCompatOrientationCapability;
- }
-
- /**
- * Whether sending compat fake focus for split screen resumed activities is enabled. Needed
- * because some game engines wait to get focus before drawing the content of the app which isn't
- * guaranteed by default in multi-window modes.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the treatment is enabled
- * <li>Component property is NOT set to false
- * <li>Component property is set to true or per-app override is enabled
- * </ul>
- */
- boolean shouldSendFakeFocus() {
- return mFakeFocusOptProp.shouldEnableWithOverrideAndProperty(
- isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS));
- }
-
- /**
- * Whether activity is eligible for camera compat force rotation treatment. See {@link
- * DisplayRotationCompatPolicy} for context.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the camera compat treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override or by the app
- * developers with the component property.
- * </ul>
- */
- boolean shouldForceRotateForCameraCompat() {
- return mCameraCompatAllowForceRotationOptProp.shouldEnableWithOptOutOverrideAndProperty(
- isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION));
- }
-
- /**
- * Whether activity is eligible for activity "refresh" after camera compat force rotation
- * treatment. See {@link DisplayRotationCompatPolicy} for context.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the camera compat treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override or by the app
- * developers with the component property.
- * </ul>
- */
- boolean shouldRefreshActivityForCameraCompat() {
- return mCameraCompatAllowRefreshOptProp.shouldEnableWithOptOutOverrideAndProperty(
- isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH));
- }
-
- /**
- * Whether activity should be "refreshed" after the camera compat force rotation treatment
- * using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
- * -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the camera compat treatment is enabled.
- * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
- * component property by the app developers.
- * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
- * manufacturer with override / by the app developers with the component property.
- * </ul>
- */
- boolean shouldRefreshActivityViaPauseForCameraCompat() {
- return mCameraCompatEnableRefreshViaPauseOptProp.shouldEnableWithOverrideAndProperty(
- isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE));
- }
-
- boolean isSystemOverrideToFullscreenEnabled(int userAspectRatio) {
- return mIsSystemOverrideToFullscreenEnabled
- && !mAllowOrientationOverrideOptProp.isFalse()
- && (userAspectRatio == USER_MIN_ASPECT_RATIO_UNSET
- || userAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN);
- }
-
- boolean isAllowOrientationOverrideOptOut() {
- return mAllowOrientationOverrideOptProp.isFalse();
- }
-
- /**
- * Whether we should apply the min aspect ratio per-app override. When this override is applied
- * the min aspect ratio given in the app's manifest will be overridden to the largest enabled
- * aspect ratio treatment unless the app's manifest value is higher. The treatment will also
- * apply if no value is provided in the manifest.
- *
- * <p>This method returns {@code true} when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Per-app override is enabled
- * </ul>
- */
- boolean shouldOverrideMinAspectRatio() {
- return mAllowMinAspectRatioOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
- isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO));
- }
-
- boolean isOverrideRespectRequestedOrientationEnabled() {
- return mIsOverrideRespectRequestedOrientationEnabled;
- }
-
- boolean isOverrideOrientationOnlyForCameraEnabled() {
- return mIsOverrideOrientationOnlyForCameraEnabled;
- }
-
- /**
- * Whether activity is eligible for camera compatibility free-form treatment.
- *
- * <p>The treatment is applied to a fixed-orientation camera activity in free-form windowing
- * mode. The treatment letterboxes or pillarboxes the activity to the expected orientation and
- * provides changes to the camera and display orientation signals to match those expected on a
- * portrait device in that orientation (for example, on a standard phone).
- *
- * <p>The treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Property gating the camera compatibility free-form treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override.
- * </ul>
- */
- boolean shouldApplyFreeformTreatmentForCameraCompat() {
- return Flags.cameraCompatForFreeform() && !isCompatChangeEnabled(
- OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT);
- }
-
-
- /**
- * Whether we should apply the min aspect ratio per-app override only when an app is connected
- * to the camera.
- * When this override is applied the min aspect ratio given in the app's manifest will be
- * overridden to the largest enabled aspect ratio treatment unless the app's manifest value
- * is higher. The treatment will also apply if no value is provided in the manifest.
- *
- * <p>This method returns {@code true} when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Per-app override is enabled
- * </ul>
- */
- boolean shouldOverrideMinAspectRatioForCamera() {
- return mActivityRecord.isCameraActive()
- && mAllowMinAspectRatioOverrideOptProp
- .shouldEnableWithOptInOverrideAndOptOutProperty(
- isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA));
- }
-
- /**
- * Whether should fix display orientation to landscape natural orientation when a task is
- * fullscreen and the display is ignoring orientation requests.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Opt-in per-app override is enabled
- * <li>Task is in fullscreen.
- * <li>{@link DisplayContent#getIgnoreOrientationRequest} is enabled
- * <li>Natural orientation of the display is landscape.
- * </ul>
- */
- boolean shouldUseDisplayLandscapeNaturalOrientation() {
- return mAllowDisplayOrientationOverrideOptProp
- .shouldEnableWithOptInOverrideAndOptOutProperty(
- isCompatChangeEnabled(OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION));
- }
-
- /**
- * Whether we should apply the force resize per-app override. When this override is applied it
- * forces the packages it is applied to to be resizable. It won't change whether the app can be
- * put into multi-windowing mode, but allow the app to resize without going into size-compat
- * mode when the window container resizes, such as display size change or screen rotation.
- *
- * <p>This method returns {@code true} when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Per-app override is enabled
- * </ul>
- */
- boolean shouldOverrideForceResizeApp() {
- return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
- isCompatChangeEnabled(FORCE_RESIZE_APP));
- }
-
- /**
- * Whether we should enable users to resize the current app.
- */
- boolean shouldEnableUserAspectRatioSettings() {
- // We use mBooleanPropertyAllowUserAspectRatioOverride to allow apps to opt-out which has
- // effect only if explicitly false. If mBooleanPropertyAllowUserAspectRatioOverride is null,
- // the current app doesn't opt-out so the first part of the predicate is true.
- return !mAllowUserAspectRatioOverrideOptProp.isFalse()
- && mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
- && mActivityRecord.mDisplayContent != null
- && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest();
- }
-
- boolean isUserFullscreenOverrideEnabled() {
- if (mAllowUserAspectRatioOverrideOptProp.isFalse()
- || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse()
- || !mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()) {
- return false;
- }
- return true;
- }
-
- /**
- * Whether we should apply the force non resize per-app override. When this override is applied
- * it forces the packages it is applied to to be non-resizable.
- *
- * <p>This method returns {@code true} when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Per-app override is enabled
- * </ul>
- */
- boolean shouldOverrideForceNonResizeApp() {
- return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
- isCompatChangeEnabled(FORCE_NON_RESIZE_APP));
- }
-
- private boolean isCompatChangeEnabled(long overrideChangeId) {
- return mActivityRecord.info.isChangeEnabled(overrideChangeId);
- }
-
- @NonNull
- static BooleanSupplier asLazy(@NonNull BooleanSupplier supplier) {
- return new BooleanSupplier() {
- private boolean mRead;
- private boolean mValue;
-
- @Override
- public boolean getAsBoolean() {
- if (!mRead) {
- mRead = true;
- mValue = supplier.getAsBoolean();
- }
- return mValue;
- }
- };
- }
-}
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
index 3ff0fce..d8c0c17 100644
--- a/services/core/java/com/android/server/wm/AppCompatController.java
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
import android.annotation.NonNull;
+import android.content.pm.PackageManager;
+
+import com.android.server.wm.utils.OptPropFactory;
/**
* Allows the interaction with all the app compat policies and configurations
@@ -27,20 +30,27 @@
@NonNull
private final AppCompatOrientationPolicy mOrientationPolicy;
@NonNull
- private final AppCompatCapability mAppCompatCapability;
+ private final AppCompatOverrides mAppCompatOverrides;
+ @NonNull
+ private final AppCompatCameraPolicy mAppCompatCameraPolicy;
AppCompatController(@NonNull WindowManagerService wmService,
@NonNull ActivityRecord activityRecord) {
+ final PackageManager packageManager = wmService.mContext.getPackageManager();
+ final OptPropFactory optPropBuilder = new OptPropFactory(packageManager,
+ activityRecord.packageName);
mTransparentPolicy = new TransparentPolicy(activityRecord,
wmService.mLetterboxConfiguration);
- mAppCompatCapability = new AppCompatCapability(wmService, activityRecord,
- wmService.mLetterboxConfiguration);
+ mAppCompatOverrides = new AppCompatOverrides(activityRecord,
+ wmService.mLetterboxConfiguration, optPropBuilder);
// TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with aspectRatio.
final LetterboxUiController tmpController = activityRecord.mLetterboxUiController;
mOrientationPolicy = new AppCompatOrientationPolicy(activityRecord,
- mAppCompatCapability, tmpController::shouldApplyUserFullscreenOverride,
+ mAppCompatOverrides, tmpController::shouldApplyUserFullscreenOverride,
tmpController::shouldApplyUserMinAspectRatioOverride,
tmpController::isSystemOverrideToFullscreenEnabled);
+ mAppCompatCameraPolicy = new AppCompatCameraPolicy(activityRecord,
+ mAppCompatOverrides.getAppCompatCameraOverrides());
}
@NonNull
@@ -54,7 +64,22 @@
}
@NonNull
- AppCompatCapability getAppCompatCapability() {
- return mAppCompatCapability;
+ AppCompatCameraPolicy getAppCompatCameraPolicy() {
+ return mAppCompatCameraPolicy;
+ }
+
+ @NonNull
+ AppCompatOverrides getAppCompatOverrides() {
+ return mAppCompatOverrides;
+ }
+
+ @NonNull
+ AppCompatOrientationOverrides getAppCompatOrientationOverrides() {
+ return mAppCompatOverrides.getAppCompatOrientationOverrides();
+ }
+
+ @NonNull
+ AppCompatCameraOverrides getAppCompatCameraOverrides() {
+ return mAppCompatOverrides.getAppCompatCameraOverrides();
}
}
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationCapability.java b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
similarity index 89%
rename from services/core/java/com/android/server/wm/AppCompatOrientationCapability.java
rename to services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
index 10f3e83..b0fdbb5 100644
--- a/services/core/java/com/android/server/wm/AppCompatOrientationCapability.java
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
@@ -28,7 +28,7 @@
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.AppCompatCapability.asLazy;
+import static com.android.server.wm.AppCompatUtils.asLazy;
import android.annotation.NonNull;
import android.content.pm.ActivityInfo;
@@ -40,9 +40,14 @@
import java.util.function.BooleanSupplier;
import java.util.function.LongSupplier;
-class AppCompatOrientationCapability {
+/**
+ * Encapsulates all the configurations and overrides about orientation used by
+ * {@link AppCompatOrientationPolicy}.
+ */
+class AppCompatOrientationOverrides {
- private static final String TAG = TAG_WITH_CLASS_NAME ? "AppCompatCapability" : TAG_ATM;
+ private static final String TAG = TAG_WITH_CLASS_NAME
+ ? "AppCompatOrientationOverrides" : TAG_ATM;
@NonNull
private final ActivityRecord mActivityRecord;
@@ -53,13 +58,13 @@
private final OptPropFactory.OptProp mAllowIgnoringOrientationRequestWhenLoopDetectedOptProp;
@NonNull
- final OrientationCapabilityState mOrientationCapabilityState;
+ final OrientationOverridesState mOrientationOverridesState;
- AppCompatOrientationCapability(@NonNull OptPropFactory optPropBuilder,
- @NonNull LetterboxConfiguration letterboxConfiguration,
- @NonNull ActivityRecord activityRecord) {
+ AppCompatOrientationOverrides(@NonNull ActivityRecord activityRecord,
+ @NonNull LetterboxConfiguration letterboxConfiguration,
+ @NonNull OptPropFactory optPropBuilder) {
mActivityRecord = activityRecord;
- mOrientationCapabilityState = new OrientationCapabilityState(mActivityRecord,
+ mOrientationOverridesState = new OrientationOverridesState(mActivityRecord,
System::currentTimeMillis);
final BooleanSupplier isPolicyForIgnoringRequestedOrientationEnabled = asLazy(
letterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled);
@@ -101,7 +106,7 @@
@ActivityInfo.ScreenOrientation int requestedOrientation) {
if (mIgnoreRequestedOrientationOptProp.shouldEnableWithOverrideAndProperty(
isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION))) {
- if (mOrientationCapabilityState.mIsRelaunchingAfterRequestedOrientationChanged) {
+ if (mOrientationOverridesState.mIsRelaunchingAfterRequestedOrientationChanged) {
Slog.w(TAG, "Ignoring orientation update to "
+ screenOrientationToString(requestedOrientation)
+ " due to relaunching after setRequestedOrientation for "
@@ -150,9 +155,9 @@
.shouldEnableWithOptInOverrideAndOptOutProperty(loopDetectionEnabled)) {
return false;
}
- mOrientationCapabilityState.updateOrientationRequestLoopState();
+ mOrientationOverridesState.updateOrientationRequestLoopState();
- return mOrientationCapabilityState.shouldIgnoreRequestInLoop()
+ return mOrientationOverridesState.shouldIgnoreRequestInLoop()
&& !mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio();
}
@@ -161,17 +166,17 @@
* android.app.Activity#setRequestedOrientation}.
*/
void setRelaunchingAfterRequestedOrientationChanged(boolean isRelaunching) {
- mOrientationCapabilityState
+ mOrientationOverridesState
.mIsRelaunchingAfterRequestedOrientationChanged = isRelaunching;
}
boolean getIsRelaunchingAfterRequestedOrientationChanged() {
- return mOrientationCapabilityState.mIsRelaunchingAfterRequestedOrientationChanged;
+ return mOrientationOverridesState.mIsRelaunchingAfterRequestedOrientationChanged;
}
@VisibleForTesting
int getSetOrientationRequestCounter() {
- return mOrientationCapabilityState.mSetOrientationRequestCounter;
+ return mOrientationOverridesState.mSetOrientationRequestCounter;
}
private boolean isCompatChangeEnabled(long overrideChangeId) {
@@ -192,7 +197,7 @@
.isTreatmentEnabledForActivity(mActivityRecord);
}
- static class OrientationCapabilityState {
+ static class OrientationOverridesState {
// Corresponds to OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR
final boolean mIsOverrideToNosensorOrientationEnabled;
// Corresponds to OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT
@@ -219,7 +224,7 @@
@VisibleForTesting
LongSupplier mCurrentTimeMillisSupplier;
- OrientationCapabilityState(@NonNull ActivityRecord activityRecord,
+ OrientationOverridesState(@NonNull ActivityRecord activityRecord,
@NonNull LongSupplier currentTimeMillisSupplier) {
mCurrentTimeMillisSupplier = currentTimeMillisSupplier;
mIsOverrideToNosensorOrientationEnabled =
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
index c505ff9..960ef5a 100644
--- a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
@@ -45,7 +45,7 @@
private final ActivityRecord mActivityRecord;
@NonNull
- private final AppCompatCapability mAppCompatCapability;
+ private final AppCompatOverrides mAppCompatOverrides;
@NonNull
private final BooleanSupplier mShouldApplyUserFullscreenOverride;
@@ -56,12 +56,12 @@
// TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with spectRatio component
AppCompatOrientationPolicy(@NonNull ActivityRecord activityRecord,
- @NonNull AppCompatCapability appCompatCapability,
+ @NonNull AppCompatOverrides appCompatOverrides,
@NonNull BooleanSupplier shouldApplyUserFullscreenOverride,
@NonNull BooleanSupplier shouldApplyUserMinAspectRatioOverride,
@NonNull BooleanSupplier isSystemOverrideToFullscreenEnabled) {
mActivityRecord = activityRecord;
- mAppCompatCapability = appCompatCapability;
+ mAppCompatOverrides = appCompatOverrides;
mShouldApplyUserFullscreenOverride = shouldApplyUserFullscreenOverride;
mShouldApplyUserMinAspectRatioOverride = shouldApplyUserMinAspectRatioOverride;
mIsSystemOverrideToFullscreenEnabled = isSystemOverrideToFullscreenEnabled;
@@ -99,15 +99,15 @@
return SCREEN_ORIENTATION_PORTRAIT;
}
- if (mAppCompatCapability.isAllowOrientationOverrideOptOut()) {
+ if (mAppCompatOverrides.isAllowOrientationOverrideOptOut()) {
return candidate;
}
- if (displayContent != null && mAppCompatCapability
+ if (displayContent != null && mAppCompatOverrides.getAppCompatCameraOverrides()
.isOverrideOrientationOnlyForCameraEnabled()
- && (displayContent.mDisplayRotationCompatPolicy == null
- || !displayContent.mDisplayRotationCompatPolicy
- .isActivityEligibleForOrientationOverride(mActivityRecord))) {
+ && (displayContent.mDisplayRotationCompatPolicy == null
+ || !displayContent.mDisplayRotationCompatPolicy
+ .isActivityEligibleForOrientationOverride(mActivityRecord))) {
return candidate;
}
@@ -127,9 +127,9 @@
return SCREEN_ORIENTATION_USER;
}
- final AppCompatOrientationCapability.OrientationCapabilityState capabilityState =
- mAppCompatCapability.getAppCompatOrientationCapability()
- .mOrientationCapabilityState;
+ final AppCompatOrientationOverrides.OrientationOverridesState capabilityState =
+ mAppCompatOverrides.getAppCompatOrientationOverrides()
+ .mOrientationOverridesState;
if (capabilityState.mIsOverrideToReverseLandscapeOrientationEnabled
&& (isFixedOrientationLandscape(candidate)
diff --git a/services/core/java/com/android/server/wm/AppCompatOverrides.java b/services/core/java/com/android/server/wm/AppCompatOverrides.java
new file mode 100644
index 0000000..c20da7c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatOverrides.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2024 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.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
+import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
+import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
+import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.NonNull;
+
+import com.android.server.wm.utils.OptPropFactory;
+
+/**
+ * Encapsulate logic related to operations guarded by an app override.
+ */
+public class AppCompatOverrides {
+
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "AppCompatOverrides" : TAG_ATM;
+
+ @NonNull
+ private final LetterboxConfiguration mLetterboxConfiguration;
+
+ @NonNull
+ private final ActivityRecord mActivityRecord;
+
+ @NonNull
+ private final OptPropFactory.OptProp mFakeFocusOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowOrientationOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowDisplayOrientationOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowForceResizeOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowUserAspectRatioOverrideOptProp;
+ @NonNull
+ private final OptPropFactory.OptProp mAllowUserAspectRatioFullscreenOverrideOptProp;
+ @NonNull
+ private final AppCompatOrientationOverrides mAppCompatOrientationOverrides;
+ @NonNull
+ private final AppCompatCameraOverrides mAppCompatCameraOverrides;
+
+ AppCompatOverrides(@NonNull ActivityRecord activityRecord,
+ @NonNull LetterboxConfiguration letterboxConfiguration,
+ @NonNull OptPropFactory optPropBuilder) {
+ mLetterboxConfiguration = letterboxConfiguration;
+ mActivityRecord = activityRecord;
+
+ mAppCompatOrientationOverrides = new AppCompatOrientationOverrides(mActivityRecord,
+ mLetterboxConfiguration, optPropBuilder);
+ mAppCompatCameraOverrides = new AppCompatCameraOverrides(mActivityRecord,
+ mLetterboxConfiguration, optPropBuilder);
+
+ mFakeFocusOptProp = optPropBuilder.create(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS,
+ mLetterboxConfiguration::isCompatFakeFocusEnabled);
+
+
+ mAllowOrientationOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+
+ mAllowDisplayOrientationOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE,
+ () -> mActivityRecord.mDisplayContent != null
+ && mActivityRecord.getTask() != null
+ && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest()
+ && !mActivityRecord.getTask().inMultiWindowMode()
+ && mActivityRecord.mDisplayContent.getNaturalOrientation()
+ == ORIENTATION_LANDSCAPE
+ );
+
+ mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
+ mAllowForceResizeOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES);
+ mAllowUserAspectRatioOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE,
+ mLetterboxConfiguration::isUserAppAspectRatioSettingsEnabled);
+ mAllowUserAspectRatioFullscreenOverrideOptProp = optPropBuilder.create(
+ PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
+ mLetterboxConfiguration::isUserAppAspectRatioFullscreenEnabled);
+ }
+
+ /**
+ * @return {@code true} if the App Compat Camera Policy is active for the current activity.
+ */
+ boolean isCameraCompatTreatmentActive() {
+ final DisplayContent displayContent = mActivityRecord.mDisplayContent;
+ if (displayContent == null) {
+ return false;
+ }
+ return displayContent.mDisplayRotationCompatPolicy != null
+ && displayContent.mDisplayRotationCompatPolicy
+ .isTreatmentEnabledForActivity(mActivityRecord);
+ }
+
+ @NonNull
+ AppCompatOrientationOverrides getAppCompatOrientationOverrides() {
+ return mAppCompatOrientationOverrides;
+ }
+
+ @NonNull
+ AppCompatCameraOverrides getAppCompatCameraOverrides() {
+ return mAppCompatCameraOverrides;
+ }
+
+ /**
+ * Whether sending compat fake focus for split screen resumed activities is enabled. Needed
+ * because some game engines wait to get focus before drawing the content of the app which isn't
+ * guaranteed by default in multi-window modes.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the treatment is enabled
+ * <li>Component property is NOT set to false
+ * <li>Component property is set to true or per-app override is enabled
+ * </ul>
+ */
+ boolean shouldSendFakeFocus() {
+ return mFakeFocusOptProp.shouldEnableWithOverrideAndProperty(
+ isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS));
+ }
+
+ boolean isSystemOverrideToFullscreenEnabled(int userAspectRatio) {
+ return isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION_TO_USER)
+ && !mAllowOrientationOverrideOptProp.isFalse()
+ && (userAspectRatio == USER_MIN_ASPECT_RATIO_UNSET
+ || userAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN);
+ }
+
+ boolean isAllowOrientationOverrideOptOut() {
+ return mAllowOrientationOverrideOptProp.isFalse();
+ }
+
+ /**
+ * Whether we should apply the min aspect ratio per-app override. When this override is applied
+ * the min aspect ratio given in the app's manifest will be overridden to the largest enabled
+ * aspect ratio treatment unless the app's manifest value is higher. The treatment will also
+ * apply if no value is provided in the manifest.
+ *
+ * <p>This method returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>Opt-out component property isn't enabled
+ * <li>Per-app override is enabled
+ * </ul>
+ */
+ boolean shouldOverrideMinAspectRatio() {
+ return mAllowMinAspectRatioOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
+ isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO));
+ }
+
+ boolean isOverrideRespectRequestedOrientationEnabled() {
+ return isCompatChangeEnabled(OVERRIDE_RESPECT_REQUESTED_ORIENTATION);
+ }
+
+ /**
+ * Whether should fix display orientation to landscape natural orientation when a task is
+ * fullscreen and the display is ignoring orientation requests.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Opt-out component property isn't enabled
+ * <li>Opt-in per-app override is enabled
+ * <li>Task is in fullscreen.
+ * <li>{@link DisplayContent#getIgnoreOrientationRequest} is enabled
+ * <li>Natural orientation of the display is landscape.
+ * </ul>
+ */
+ boolean shouldUseDisplayLandscapeNaturalOrientation() {
+ return mAllowDisplayOrientationOverrideOptProp
+ .shouldEnableWithOptInOverrideAndOptOutProperty(
+ isCompatChangeEnabled(OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION));
+ }
+
+ /**
+ * Whether we should apply the force resize per-app override. When this override is applied it
+ * forces the packages it is applied to to be resizable. It won't change whether the app can be
+ * put into multi-windowing mode, but allow the app to resize without going into size-compat
+ * mode when the window container resizes, such as display size change or screen rotation.
+ *
+ * <p>This method returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>Opt-out component property isn't enabled
+ * <li>Per-app override is enabled
+ * </ul>
+ */
+ boolean shouldOverrideForceResizeApp() {
+ return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
+ isCompatChangeEnabled(FORCE_RESIZE_APP));
+ }
+
+ /**
+ * Whether we should enable users to resize the current app.
+ */
+ boolean shouldEnableUserAspectRatioSettings() {
+ // We use mBooleanPropertyAllowUserAspectRatioOverride to allow apps to opt-out which has
+ // effect only if explicitly false. If mBooleanPropertyAllowUserAspectRatioOverride is null,
+ // the current app doesn't opt-out so the first part of the predicate is true.
+ return !mAllowUserAspectRatioOverrideOptProp.isFalse()
+ && mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
+ && mActivityRecord.mDisplayContent != null
+ && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest();
+ }
+
+ boolean isUserFullscreenOverrideEnabled() {
+ if (mAllowUserAspectRatioOverrideOptProp.isFalse()
+ || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse()
+ || !mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Whether we should apply the force non resize per-app override. When this override is applied
+ * it forces the packages it is applied to to be non-resizable.
+ *
+ * <p>This method returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>Opt-out component property isn't enabled
+ * <li>Per-app override is enabled
+ * </ul>
+ */
+ boolean shouldOverrideForceNonResizeApp() {
+ return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
+ isCompatChangeEnabled(FORCE_NON_RESIZE_APP));
+ }
+
+ private boolean isCompatChangeEnabled(long overrideChangeId) {
+ return mActivityRecord.info.isChangeEnabled(overrideChangeId);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java
new file mode 100644
index 0000000..be51dd3b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatUtils.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 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 java.util.function.BooleanSupplier;
+
+/**
+ * Utilities for App Compat policies and overrides.
+ */
+class AppCompatUtils {
+
+ /**
+ * Lazy version of a {@link BooleanSupplier} which access an existing BooleanSupplier and
+ * caches the value.
+ *
+ * @param supplier The BooleanSupplier to decorate.
+ * @return A lazy implementation of a BooleanSupplier
+ */
+ @NonNull
+ static BooleanSupplier asLazy(@NonNull BooleanSupplier supplier) {
+ return new BooleanSupplier() {
+ private boolean mRead;
+ private boolean mValue;
+
+ @Override
+ public boolean getAsBoolean() {
+ if (!mRead) {
+ mRead = true;
+ mValue = supplier.getAsBoolean();
+ }
+ return mValue;
+ }
+ };
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c2b9128..bc7e84a 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -135,7 +135,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.TransitionAnimation;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.DumpUtils.Dump;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index c55a100..44b414f 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -92,7 +92,7 @@
import android.window.ITaskFragmentOrganizer;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index a8cc2ae..4554b21 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -30,7 +30,7 @@
import android.view.SurfaceControl;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.util.ArrayList;
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 14ae918..d45ed12 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -61,7 +61,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.window.flags.Flags;
import java.io.PrintWriter;
@@ -357,8 +357,7 @@
removedWindowContainer);
mBackAnimationInProgress = builder != null;
if (mBackAnimationInProgress) {
- if (removedWindowContainer.hasCommittedReparentToAnimationLeash()
- || removedWindowContainer.mTransitionController.inTransition()
+ if (removedWindowContainer.mTransitionController.inTransition()
|| mWindowManagerService.mSyncEngine.hasPendingSyncSets()) {
ProtoLog.w(WM_DEBUG_BACK_PREVIEW,
"Pending back animation due to another animation is running");
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 0b2c851..ba4ab7d 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -22,7 +22,7 @@
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.io.PrintWriter;
import java.util.function.Supplier;
diff --git a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
index 0c751cf..68a4172 100644
--- a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
+++ b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
@@ -32,7 +32,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.window.flags.Flags;
/**
@@ -110,12 +110,14 @@
if (!isTreatmentEnabledForActivity(cameraActivity)) {
return false;
}
- final int existingCameraCompatMode =
- cameraActivity.mLetterboxUiController.getFreeformCameraCompatMode();
+ final int existingCameraCompatMode = cameraActivity.mAppCompatController
+ .getAppCompatCameraOverrides()
+ .getFreeformCameraCompatMode();
final int newCameraCompatMode = getCameraCompatMode(cameraActivity);
if (newCameraCompatMode != existingCameraCompatMode) {
mIsCameraCompatTreatmentPending = true;
- cameraActivity.mLetterboxUiController.setFreeformCameraCompatMode(newCameraCompatMode);
+ cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .setFreeformCameraCompatMode(newCameraCompatMode);
forceUpdateActivityAndTask(cameraActivity);
return true;
} else {
@@ -134,8 +136,8 @@
mDisplayContent.mDisplayId, cameraId);
return false;
}
- cameraActivity.mLetterboxUiController.setFreeformCameraCompatMode(
- CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE);
+ cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .setFreeformCameraCompatMode(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE);
forceUpdateActivityAndTask(cameraActivity);
mIsCameraCompatTreatmentPending = false;
return true;
@@ -191,6 +193,6 @@
|| mCameraStateMonitor.isCameraWithIdRunningForActivity(topActivity, cameraId)) {
return false;
}
- return topActivity.mLetterboxUiController.isRefreshRequested();
+ return topActivity.mAppCompatController.getAppCompatCameraOverrides().isRefreshRequested();
}
}
diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java
index ea7edea..a54141c 100644
--- a/services/core/java/com/android/server/wm/CameraStateMonitor.java
+++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java
@@ -26,7 +26,7 @@
import android.util.ArraySet;
import android.util.Slog;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.util.ArrayList;
import java.util.List;
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index b795987f..44202a2 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -48,7 +48,7 @@
import android.util.SparseBooleanArray;
import android.util.Xml;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index d70a880..7e7073c 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -42,7 +42,7 @@
import android.view.SurfaceControl;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.display.feature.DisplayManagerFlags;
/**
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index b589085..283f819 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -23,7 +23,7 @@
import android.view.ContentRecordingSession;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
/**
* Orchestrates the handoff between displays if the recording session changes, and keeps track of
diff --git a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
index be44629..3b99954 100644
--- a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
@@ -36,7 +36,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.wm.utils.DisplayInfoOverrides.DisplayInfoFieldsUpdater;
import com.android.window.flags.Flags;
diff --git a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
index 735c73a..22fa88f 100644
--- a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
+++ b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
@@ -29,7 +29,7 @@
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 0006bd2..def495f 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -45,7 +45,7 @@
import android.window.IDisplayAreaOrganizer;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
index 3dc3be9..8f471d7 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
@@ -33,7 +33,7 @@
import android.window.IDisplayAreaOrganizerController;
import android.window.WindowContainerToken;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
index 8c52288..bb596cc 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
@@ -42,7 +42,7 @@
import com.android.internal.annotations.Keep;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
import java.util.ArrayList;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7ffffe9..b5b9377 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -254,7 +254,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 4a59fc2..80362a4 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -132,7 +132,7 @@
import com.android.internal.policy.ForceShowNavBarSettingsObserver;
import com.android.internal.policy.GestureNavigationSettingsObserver;
import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.statusbar.LetterboxDetails;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.util.ScreenshotRequest;
@@ -782,7 +782,6 @@
}
private void onDisplaySwitchFinished() {
- mDisplayContent.mWallpaperController.onDisplaySwitchFinished();
mDisplayContent.mDisplayUpdater.onDisplaySwitching(false);
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index afcf364..f3ccc3b 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -80,7 +80,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.policy.WindowManagerPolicy;
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index 6ecafdb..3d71e95 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -42,7 +42,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.UiThread;
/**
@@ -228,9 +228,11 @@
!= lastReportedConfig.windowConfiguration.getDisplayRotation());
return isTreatmentEnabledForDisplay()
&& isTreatmentEnabledForActivity(activity)
- && activity.mLetterboxUiController.shouldRefreshActivityForCameraCompat()
+ && activity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldRefreshActivityForCameraCompat()
&& (displayRotationChanged
- || activity.mLetterboxUiController.isCameraCompatSplitScreenAspectRatioAllowed());
+ || activity.mAppCompatController.getAppCompatCameraOverrides()
+ .isCameraCompatSplitScreenAspectRatioAllowed());
}
/**
@@ -254,7 +256,8 @@
boolean isActivityEligibleForOrientationOverride(@NonNull ActivityRecord activity) {
return isTreatmentEnabledForDisplay()
&& isCameraActive(activity, /* mustBeFullscreen */ true)
- && activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
+ && activity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldForceRotateForCameraCompat();
}
/**
@@ -286,7 +289,8 @@
// handle dynamic changes so we shouldn't force rotate them.
&& activity.getOverrideOrientation() != SCREEN_ORIENTATION_NOSENSOR
&& activity.getOverrideOrientation() != SCREEN_ORIENTATION_LOCKED
- && activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
+ && activity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldForceRotateForCameraCompat();
}
@Override
@@ -295,7 +299,8 @@
// Checking whether an activity in fullscreen rather than the task as this camera
// compat treatment doesn't cover activity embedding.
if (cameraActivity.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
- cameraActivity.mLetterboxUiController.recomputeConfigurationForCameraCompatIfNeeded();
+ cameraActivity.mAppCompatController
+ .getAppCompatCameraPolicy().recomputeConfigurationForCameraCompatIfNeeded();
mDisplayContent.updateOrientation();
return true;
}
@@ -362,7 +367,8 @@
|| topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
return true;
}
- topActivity.mLetterboxUiController.recomputeConfigurationForCameraCompatIfNeeded();
+ topActivity.mAppCompatController
+ .getAppCompatCameraPolicy().recomputeConfigurationForCameraCompatIfNeeded();
mDisplayContent.updateOrientation();
return true;
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotationReversionController.java b/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
index 50b29ec..f94b8c4 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
@@ -26,7 +26,7 @@
import android.content.ActivityInfoProto;
import android.view.Surface;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
/**
* Defines the behavior of reversion from device rotation overrides.
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
index c79565a..8bd8098 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.os.UserHandle.USER_SYSTEM;
import static android.view.Display.TYPE_VIRTUAL;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
@@ -27,6 +28,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.WindowConfiguration;
import android.os.Environment;
import android.util.ArrayMap;
@@ -42,6 +44,7 @@
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.wm.DisplayWindowSettings.SettingsProvider;
+import com.android.window.flags.Flags;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -53,6 +56,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
+import java.util.Set;
/**
* Implementation of {@link SettingsProvider} that reads the base settings provided in a display
@@ -91,11 +95,11 @@
@NonNull
private ReadableSettings mBaseSettings;
@NonNull
- private final WritableSettings mOverrideSettings;
+ private WritableSettings mOverrideSettings;
DisplayWindowSettingsProvider() {
this(new AtomicFileStorage(getVendorSettingsFile()),
- new AtomicFileStorage(getOverrideSettingsFile()));
+ new AtomicFileStorage(getOverrideSettingsFileForUser(USER_SYSTEM)));
}
@VisibleForTesting
@@ -133,6 +137,48 @@
mBaseSettings = new ReadableSettings(baseSettingsStorage);
}
+ /**
+ * Overrides the storage that should be used to save override settings for a user.
+ *
+ * @see #DATA_DISPLAY_SETTINGS_FILE_PATH
+ */
+ void setOverrideSettingsForUser(@UserIdInt int userId) {
+ if (!Flags.perUserDisplayWindowSettings()) {
+ return;
+ }
+ final AtomicFile settingsFile = getOverrideSettingsFileForUser(userId);
+ setOverrideSettingsStorage(new AtomicFileStorage(settingsFile));
+ }
+
+ /**
+ * Removes display override settings that are no longer associated with active displays.
+ * This is necessary because displays can be dynamically added or removed during
+ * the system's lifecycle (e.g., user switch, system server restart).
+ *
+ * @param root The root window container used to obtain the currently active displays.
+ */
+ void removeStaleDisplaySettings(@NonNull RootWindowContainer root) {
+ if (!Flags.perUserDisplayWindowSettings()) {
+ return;
+ }
+ final Set<String> displayIdentifiers = new ArraySet<>();
+ root.forAllDisplays(dc -> {
+ final String identifier = mOverrideSettings.getIdentifier(dc.getDisplayInfo());
+ displayIdentifiers.add(identifier);
+ });
+ mOverrideSettings.removeStaleDisplaySettings(displayIdentifiers);
+ }
+
+ /**
+ * Overrides the storage that should be used to save override settings.
+ *
+ * @see #setOverrideSettingsForUser(int)
+ */
+ @VisibleForTesting
+ void setOverrideSettingsStorage(@NonNull WritableSettingsStorage overrideSettingsStorage) {
+ mOverrideSettings = new WritableSettings(overrideSettingsStorage);
+ }
+
@Override
@NonNull
public SettingsEntry getSettings(@NonNull DisplayInfo info) {
@@ -302,6 +348,12 @@
mVirtualDisplayIdentifiers.remove(identifier);
}
+ void removeStaleDisplaySettings(@NonNull Set<String> currentDisplayIdentifiers) {
+ if (mSettings.retainAll(currentDisplayIdentifiers)) {
+ writeSettings();
+ }
+ }
+
private void writeSettings() {
final FileData fileData = new FileData();
fileData.mIdentifierType = mIdentifierType;
@@ -332,9 +384,14 @@
}
@NonNull
- private static AtomicFile getOverrideSettingsFile() {
- final File overrideSettingsFile = new File(Environment.getDataDirectory(),
- DATA_DISPLAY_SETTINGS_FILE_PATH);
+ private static AtomicFile getOverrideSettingsFileForUser(@UserIdInt int userId) {
+ final File directory;
+ if (userId == USER_SYSTEM || !Flags.perUserDisplayWindowSettings()) {
+ directory = Environment.getDataDirectory();
+ } else {
+ directory = Environment.getDataSystemCeDirectory(userId);
+ }
+ final File overrideSettingsFile = new File(directory, DATA_DISPLAY_SETTINGS_FILE_PATH);
return new AtomicFile(overrideSettingsFile, WM_DISPLAY_COMMIT_TAG);
}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index e3827aa..4be5bad 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -64,7 +64,7 @@
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.view.IDragAndDropPermissions;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index a21ba26..c66d659 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -35,7 +35,7 @@
import android.view.InputChannel;
import android.window.InputTransferToken;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.input.InputManagerService;
/**
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 156e9f9..91c61b1 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -40,7 +40,7 @@
import android.view.inputmethod.ImeTracker;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 8035a29..74dbd15 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -66,7 +66,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.inputmethod.InputMethodManagerInternal;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index f68b67f6..33dea54 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -48,7 +48,7 @@
import android.view.WindowInsets;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.TriFunction;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index a967f7a..3483842 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -41,7 +41,7 @@
import android.view.WindowInsets;
import android.view.WindowInsets.Type.InsetsType;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.inputmethod.InputMethodManagerInternal;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index f70d2a5..872b4e1 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING;
@@ -657,7 +656,6 @@
final boolean lastKeyguardGoingAway = mKeyguardGoingAway;
final ActivityRecord lastDismissKeyguardActivity = mDismissingKeyguardActivity;
- final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity;
mRequestDismissKeyguard = false;
mOccluded = false;
@@ -666,7 +664,6 @@
mDismissingKeyguardActivity = null;
mTopTurnScreenOnActivity = null;
- boolean occludedByActivity = false;
final Task task = getRootTaskForControllingOccluding(display);
final ActivityRecord top = task != null ? task.getTopNonFinishingActivity() : null;
if (top != null) {
@@ -712,7 +709,7 @@
if (mTopTurnScreenOnActivity != null
&& !mService.mWindowManager.mPowerManager.isInteractive()
- && (mRequestDismissKeyguard || occludedByActivity)) {
+ && (mRequestDismissKeyguard || mOccluded)) {
controller.mTaskSupervisor.wakeUp("handleTurnScreenOn");
mTopTurnScreenOnActivity.setCurrentLaunchCanTurnScreenOn(false);
}
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index e0d2035..e924fb6 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
@@ -65,7 +64,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager.TaskDescription;
-import android.app.CameraCompatTaskInfo.FreeformCameraCompatMode;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -103,9 +101,6 @@
private final ActivityRecord mActivityRecord;
- // TODO(b/265576778): Cache other overrides as well.
-
-
private boolean mShowWallpaperForLetterboxBackground;
// TODO(b/315140179): Make mUserAspectRatio final
@@ -116,18 +111,10 @@
@Nullable
private Letterbox mLetterbox;
- // Whether activity "refresh" was requested but not finished in
- // ActivityRecord#activityResumedLocked following the camera compat force rotation in
- // DisplayRotationCompatPolicy.
- private boolean mIsRefreshRequested;
-
private boolean mLastShouldShowLetterboxUi;
private boolean mDoubleTapEvent;
- @FreeformCameraCompatMode
- private int mFreeformCameraCompatMode = CAMERA_COMPAT_FREEFORM_NONE;
-
LetterboxUiController(WindowManagerService wmService, ActivityRecord activityRecord) {
mLetterboxConfiguration = wmService.mLetterboxConfiguration;
// Given activityRecord may not be fully constructed since LetterboxUiController
@@ -150,13 +137,6 @@
}
}
-
- @VisibleForTesting
- int getSetOrientationRequestCounter() {
- return getAppCompatCapability().getAppCompatOrientationCapability()
- .getSetOrientationRequestCounter();
- }
-
/**
* Whether sending compat fake focus for split screen resumed activities is enabled. Needed
* because some game engines wait to get focus before drawing the content of the app which isn't
@@ -170,7 +150,7 @@
* </ul>
*/
boolean shouldSendFakeFocus() {
- return getAppCompatCapability().shouldSendFakeFocus();
+ return getAppCompatOverrides().shouldSendFakeFocus();
}
/**
@@ -186,24 +166,7 @@
* </ul>
*/
boolean shouldOverrideMinAspectRatio() {
- return getAppCompatCapability().shouldOverrideMinAspectRatio();
- }
-
- /**
- * Whether we should apply the min aspect ratio per-app override only when an app is connected
- * to the camera.
- * When this override is applied the min aspect ratio given in the app's manifest will be
- * overridden to the largest enabled aspect ratio treatment unless the app's manifest value
- * is higher. The treatment will also apply if no value is provided in the manifest.
- *
- * <p>This method returns {@code true} when the following conditions are met:
- * <ul>
- * <li>Opt-out component property isn't enabled
- * <li>Per-app override is enabled
- * </ul>
- */
- boolean shouldOverrideMinAspectRatioForCamera() {
- return getAppCompatCapability().shouldOverrideMinAspectRatioForCamera();
+ return getAppCompatOverrides().shouldOverrideMinAspectRatio();
}
/**
@@ -219,7 +182,7 @@
* </ul>
*/
boolean shouldOverrideForceResizeApp() {
- return getAppCompatCapability().shouldOverrideForceResizeApp();
+ return getAppCompatOverrides().shouldOverrideForceResizeApp();
}
/**
@@ -233,7 +196,7 @@
* </ul>
*/
boolean shouldOverrideForceNonResizeApp() {
- return getAppCompatCapability().shouldOverrideForceNonResizeApp();
+ return getAppCompatOverrides().shouldOverrideForceNonResizeApp();
}
/**
@@ -241,23 +204,13 @@
* android.app.Activity#setRequestedOrientation}.
*/
void setRelaunchingAfterRequestedOrientationChanged(boolean isRelaunching) {
- getAppCompatCapability().getAppCompatOrientationCapability()
+ getAppCompatOverrides().getAppCompatOrientationOverrides()
.setRelaunchingAfterRequestedOrientationChanged(isRelaunching);
}
- /**
- * Whether activity "refresh" was requested but not finished in {@link #activityResumedLocked}.
- */
- boolean isRefreshRequested() {
- return mIsRefreshRequested;
- }
-
- void setIsRefreshRequested(boolean isRequested) {
- mIsRefreshRequested = isRequested;
- }
boolean isOverrideRespectRequestedOrientationEnabled() {
- return getAppCompatCapability().isOverrideRespectRequestedOrientationEnabled();
+ return getAppCompatOverrides().isOverrideRespectRequestedOrientationEnabled();
}
/**
@@ -274,86 +227,7 @@
* </ul>
*/
boolean shouldUseDisplayLandscapeNaturalOrientation() {
- return getAppCompatCapability().shouldUseDisplayLandscapeNaturalOrientation();
- }
-
- boolean isOverrideOrientationOnlyForCameraEnabled() {
- return getAppCompatCapability().isOverrideOrientationOnlyForCameraEnabled();
- }
-
- /**
- * Whether activity is eligible for activity "refresh" after camera compat force rotation
- * treatment. See {@link DisplayRotationCompatPolicy} for context.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the camera compat treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override or by the app
- * developers with the component property.
- * </ul>
- */
- boolean shouldRefreshActivityForCameraCompat() {
- return getAppCompatCapability().shouldRefreshActivityForCameraCompat();
- }
-
- /**
- * Whether activity should be "refreshed" after the camera compat force rotation treatment
- * using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
- * -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the camera compat treatment is enabled.
- * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
- * component property by the app developers.
- * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
- * manufacturer with override / by the app developers with the component property.
- * </ul>
- */
- boolean shouldRefreshActivityViaPauseForCameraCompat() {
- return getAppCompatCapability().shouldRefreshActivityViaPauseForCameraCompat();
- }
-
- /**
- * Whether activity is eligible for camera compat force rotation treatment. See {@link
- * DisplayRotationCompatPolicy} for context.
- *
- * <p>This treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Flag gating the camera compat treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override or by the app
- * developers with the component property.
- * </ul>
- */
- boolean shouldForceRotateForCameraCompat() {
- return getAppCompatCapability().shouldForceRotateForCameraCompat();
- }
-
- /**
- * Whether activity is eligible for camera compatibility free-form treatment.
- *
- * <p>The treatment is applied to a fixed-orientation camera activity in free-form windowing
- * mode. The treatment letterboxes or pillarboxes the activity to the expected orientation and
- * provides changes to the camera and display orientation signals to match those expected on a
- * portrait device in that orientation (for example, on a standard phone).
- *
- * <p>The treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Property gating the camera compatibility free-form treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override.
- * </ul>
- */
- boolean shouldApplyFreeformTreatmentForCameraCompat() {
- return getAppCompatCapability().shouldApplyFreeformTreatmentForCameraCompat();
- }
-
- @FreeformCameraCompatMode
- int getFreeformCameraCompatMode() {
- return mFreeformCameraCompatMode;
- }
-
- void setFreeformCameraCompatMode(@FreeformCameraCompatMode int freeformCameraCompatMode) {
- mFreeformCameraCompatMode = freeformCameraCompatMode;
+ return getAppCompatOverrides().shouldUseDisplayLandscapeNaturalOrientation();
}
private boolean isCompatChangeEnabled(long overrideChangeId) {
@@ -577,27 +451,10 @@
: getDefaultMinAspectRatio();
}
- void recomputeConfigurationForCameraCompatIfNeeded() {
- if (isOverrideOrientationOnlyForCameraEnabled()
- || isCameraCompatSplitScreenAspectRatioAllowed()
- || shouldOverrideMinAspectRatioForCamera()) {
- mActivityRecord.recomputeConfiguration();
- }
- }
-
boolean isLetterboxEducationEnabled() {
return mLetterboxConfiguration.getIsEducationEnabled();
}
- /**
- * Whether we use split screen aspect ratio for the activity when camera compat treatment
- * is active because the corresponding config is enabled and activity supports resizing.
- */
- boolean isCameraCompatSplitScreenAspectRatioAllowed() {
- return mLetterboxConfiguration.isCameraCompatSplitScreenAspectRatioEnabled()
- && !mActivityRecord.shouldCreateCompatDisplayInsets();
- }
-
private boolean shouldUseSplitScreenAspectRatio(@NonNull Configuration parentConfiguration) {
final boolean isBookMode = isDisplayFullScreenAndInPosture(/* isTabletop */ false);
final boolean isNotCenteredHorizontally = getHorizontalPositionMultiplier(
@@ -608,8 +465,9 @@
// Don't resize to split screen size when in book mode if letterbox position is centered
return (isBookMode && isNotCenteredHorizontally || isTabletopMode && isLandscape)
- || isCameraCompatSplitScreenAspectRatioAllowed()
- && getAppCompatCapability().isCameraCompatTreatmentActive();
+ || mActivityRecord.mAppCompatController.getAppCompatCameraOverrides()
+ .isCameraCompatSplitScreenAspectRatioAllowed()
+ && getAppCompatOverrides().isCameraCompatTreatmentActive();
}
private float getDefaultMinAspectRatioForUnresizableApps() {
@@ -711,7 +569,7 @@
* Whether we should enable users to resize the current app.
*/
boolean shouldEnableUserAspectRatioSettings() {
- return getAppCompatCapability().shouldEnableUserAspectRatioSettings();
+ return getAppCompatOverrides().shouldEnableUserAspectRatioSettings();
}
/**
@@ -741,11 +599,11 @@
}
boolean isUserFullscreenOverrideEnabled() {
- return getAppCompatCapability().isUserFullscreenOverrideEnabled();
+ return getAppCompatOverrides().isUserFullscreenOverrideEnabled();
}
boolean isSystemOverrideToFullscreenEnabled() {
- return getAppCompatCapability().isSystemOverrideToFullscreenEnabled(mUserAspectRatio);
+ return getAppCompatOverrides().isSystemOverrideToFullscreenEnabled(mUserAspectRatio);
}
boolean hasFullscreenOverride() {
@@ -941,8 +799,8 @@
}
// TODO(b/346264992): Remove after AppCompatController refactoring
- private AppCompatCapability getAppCompatCapability() {
- return mActivityRecord.mAppCompatController.getAppCompatCapability();
+ private AppCompatOverrides getAppCompatOverrides() {
+ return mActivityRecord.mAppCompatController.getAppCompatOverrides();
}
/**
@@ -983,7 +841,7 @@
@VisibleForTesting
boolean shouldShowLetterboxUi(WindowState mainWindow) {
- if (getAppCompatCapability().getAppCompatOrientationCapability()
+ if (getAppCompatOverrides().getAppCompatOrientationOverrides()
.getIsRelaunchingAfterRequestedOrientationChanged()) {
return mLastShouldShowLetterboxUi;
}
@@ -1144,7 +1002,7 @@
}
boolean getIsRelaunchingAfterRequestedOrientationChanged() {
- return getAppCompatCapability().getAppCompatOrientationCapability()
+ return getAppCompatOverrides().getAppCompatOrientationOverrides()
.getIsRelaunchingAfterRequestedOrientationChanged();
}
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 0f9998c..0dadade 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -63,7 +63,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.telephony.CellBroadcastUtils;
import com.android.internal.widget.LockPatternUtils;
diff --git a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
index 36c092b..1a895ea 100644
--- a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
@@ -35,7 +35,7 @@
import android.view.SurfaceControl;
import android.view.WindowManager;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
index 4c797f8..3cf301c 100644
--- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -36,7 +36,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.wm.DeviceStateController.DeviceState;
public class PhysicalDisplaySwitchTransitionLauncher {
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index 4378b4f..755d4c8 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -22,7 +22,6 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.app.PictureInPictureParams;
-import android.content.ComponentName;
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.Matrix;
@@ -326,19 +325,6 @@
}
/**
- * Activity is hidden (either stopped or removed), resets the last saved snap fraction
- * so that the default bounds will be returned for the next session.
- */
- void onActivityHidden(ComponentName componentName) {
- if (mPinnedTaskListener == null) return;
- try {
- mPinnedTaskListener.onActivityHidden(componentName);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering reset reentry fraction event.", e);
- }
- }
-
- /**
* Sets the Ime state and height.
*/
void setAdjustedForIme(boolean adjustedForIme, int imeHeight) {
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index e07b72a..6f25280 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -80,7 +80,7 @@
import android.view.WindowManagerPolicyConstants.PointerEventListener;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.am.ActivityManagerService;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 469cc64..c592caf 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -42,7 +42,7 @@
import android.util.Slog;
import android.view.IRecentsAnimationRunner;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 312c4be..6f94713 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -64,7 +64,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.IResultReceiver;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 63bbb31..a8edaeb 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -45,7 +45,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.FastPrintWriter;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
diff --git a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
index c22b07a..e4962bf 100644
--- a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
+++ b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
@@ -28,7 +28,7 @@
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.util.ArrayList;
import java.util.List;
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index d497d8c..243dbc7 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -24,7 +24,7 @@
import android.content.pm.ActivityInfo;
import android.os.Debug;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.util.ArrayList;
import java.util.function.Consumer;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 6abd488..d3fc7f3 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -141,7 +141,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
import com.android.server.LocalServices;
@@ -2158,6 +2158,12 @@
// Use Task#setBoundsUnchecked to skip checking windowing mode as the windowing mode
// will be updated later after this is collected in transition.
rootTask.setBoundsUnchecked(taskFragment.getBounds());
+ // The exit-PIP activity resumes early for seamless transition. In certain
+ // scenarios, this introduces unintended addition to recents. To address this,
+ // we mark the root task for automatic removal from recents. This ensures that
+ // after the pinned activity reparents to its original task, the root task is
+ // automatically removed from the recents list.
+ rootTask.autoRemoveRecents = true;
// Move the last recents animation transaction from original task to the new one.
if (task.mLastRecentsAnimationTransaction != null) {
@@ -2860,9 +2866,6 @@
} else {
throw new RuntimeException("Create the same sleep token twice: " + token);
}
- if (isSwappingDisplay) {
- display.mWallpaperController.onDisplaySwitchStarted();
- }
return token;
}
diff --git a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
index 967f415..ad4faab 100644
--- a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
+++ b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
@@ -33,7 +33,7 @@
import android.window.IScreenRecordingCallback;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.io.PrintWriter;
import java.util.ArrayList;
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index e7bffdf..3eb3218 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -57,7 +57,7 @@
import com.android.internal.R;
import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.display.DisplayControl;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 4a0239b..310516b 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -84,7 +84,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.logging.MetricsLoggerWrapper;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.wm.WindowManagerService.H;
import com.android.window.flags.Flags;
@@ -799,7 +799,7 @@
if (changed && noSystemOverlayPermission) {
if (mAlertWindowSurfaces.isEmpty()) {
cancelAlertWindowNotification();
- } else if (mAlertWindowNotification == null) {
+ } else if (mAlertWindowNotification == null && !isSatellitePointingUiPackage()) {
mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName);
if (mShowingAlertWindowNotificationAllowed) {
mAlertWindowNotification.post();
@@ -814,6 +814,16 @@
}
}
+ // TODO b/349195999 - short term solution to not show the satellite pointing ui notification.
+ private boolean isSatellitePointingUiPackage() {
+ if (mPackageName == null || !mPackageName.equals(mService.mContext.getString(
+ com.android.internal.R.string.config_pointing_ui_package))) {
+ return false;
+ }
+ return ActivityTaskManagerService.checkPermission(
+ android.Manifest.permission.SATELLITE_COMMUNICATION, mPid, mUid) == PERMISSION_GRANTED;
+ }
+
void setShowingAlertWindowNotificationAllowed(boolean allowed) {
mShowingAlertWindowNotificationAllowed = allowed;
if (mAlertWindowNotification != null) {
@@ -869,6 +879,9 @@
pw.print(" mClientDead="); pw.print(mClientDead);
pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
pw.print(prefix); pw.print("mPackageName="); pw.println(mPackageName);
+ if (isSatellitePointingUiPackage()) {
+ pw.print(prefix); pw.println("mIsSatellitePointingUiPackage=true");
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/SmoothDimmer.java b/services/core/java/com/android/server/wm/SmoothDimmer.java
index b5d94a2..2b4d901 100644
--- a/services/core/java/com/android/server/wm/SmoothDimmer.java
+++ b/services/core/java/com/android/server/wm/SmoothDimmer.java
@@ -26,7 +26,7 @@
import android.view.SurfaceControl;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
class SmoothDimmer extends Dimmer {
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index c632714..9cfd396 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -33,7 +33,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.io.PrintWriter;
import java.io.StringWriter;
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
index 0c36d27..34abf23 100644
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java
@@ -31,7 +31,7 @@
import android.window.ScreenCapture;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
/**
* This class handles "freezing" of an Animatable. The Animatable in question should implement
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index f9c53aa..7206b36 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -181,7 +181,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
@@ -404,8 +404,6 @@
String mCallingPackage;
String mCallingFeatureId;
- private static final Rect sTmpBounds = new Rect();
-
// Last non-fullscreen bounds the task was launched in or resized to.
// The information is persisted and used to determine the appropriate root task to launch the
// task into on restore.
@@ -2864,69 +2862,6 @@
}
}
- /**
- * Calculate the maximum visible area of this task. If the task has only one app,
- * the result will be visible frame of that app. If the task has more than one apps,
- * we search from top down if the next app got different visible area.
- *
- * This effort is to handle the case where some task (eg. GMail composer) might pop up
- * a dialog that's different in size from the activity below, in which case we should
- * be dimming the entire task area behind the dialog.
- *
- * @param out the union of visible bounds.
- */
- private static void getMaxVisibleBounds(ActivityRecord token, Rect out, boolean[] foundTop) {
- // skip hidden (or about to hide) apps
- if (token.mIsExiting || !token.isClientVisible() || !token.isVisibleRequested()) {
- return;
- }
- final WindowState win = token.findMainWindow();
- if (win == null) {
- return;
- }
- if (!foundTop[0]) {
- foundTop[0] = true;
- out.setEmpty();
- }
-
- final Rect visibleFrame = sTmpBounds;
- final WindowManager.LayoutParams attrs = win.mAttrs;
- visibleFrame.set(win.getFrame());
- visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
- visibleFrame, attrs.type, win.getActivityType(), attrs.softInputMode,
- attrs.flags));
- out.union(visibleFrame);
- }
-
- /** Bounds of the task to be used for dimming, as well as touch related tests. */
- @Override
- void getDimBounds(@NonNull Rect out) {
- if (isRootTask()) {
- getBounds(out);
- return;
- }
-
- final Task rootTask = getRootTask();
- if (inFreeformWindowingMode()) {
- boolean[] foundTop = { false };
- forAllActivities(a -> { getMaxVisibleBounds(a, out, foundTop); });
- if (foundTop[0]) {
- return;
- }
- }
-
- if (!matchParentBounds()) {
- // When minimizing the root docked task when going home, we don't adjust the task bounds
- // so we need to intersect the task bounds with the root task bounds here..
- rootTask.getBounds(mTmpRect);
- mTmpRect.intersect(getBounds());
- out.set(mTmpRect);
- } else {
- out.set(getBounds());
- }
- return;
- }
-
void setDragResizing(boolean dragResizing) {
if (mDragResizing != dragResizing) {
// No need to check if allowed if it's leaving dragResize
@@ -3522,7 +3457,8 @@
appCompatTaskInfo.topActivityBoundsLetterboxed = top != null && top.areBoundsLetterboxed();
appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode = top == null
? CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE
- : top.mLetterboxUiController.getFreeformCameraCompatMode();
+ : top.mAppCompatController.getAppCompatCameraOverrides()
+ .getFreeformCameraCompatMode();
}
/**
@@ -6153,11 +6089,6 @@
return setBoundsUnchecked(!inMultiWindowMode() ? null : bounds);
}
- @Override
- public void getBounds(Rect bounds) {
- bounds.set(getBounds());
- }
-
/**
* Put a Task in this root task. Used for adding only.
* When task is added to top of the root task, the entire branch of the hierarchy (including
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index eff8315..eaf3012 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -52,7 +52,7 @@
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 3cd071b..9b2c022 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -106,7 +106,7 @@
import android.window.TaskFragmentOrganizerToken;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.am.HostingRecord;
import com.android.server.pm.pkg.AndroidPackage;
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 26315f9..b6b6cf2 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -59,7 +59,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.window.flags.Flags;
import java.lang.annotation.Retention;
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index b24d53b..6e36d427 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -57,7 +57,7 @@
import android.window.WindowContainerToken;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 9b3fb6b..972dd2e 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -59,7 +59,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.TaskResizingAlgorithm;
import com.android.internal.policy.TaskResizingAlgorithm.CtrlType;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.util.concurrent.CompletableFuture;
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index e698a3d..35a7702 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -106,7 +106,7 @@
import com.android.internal.graphics.ColorUtils;
import com.android.internal.policy.TransitionAnimation;
import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 0812323..f4ff404 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -53,7 +53,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.FgThread;
import com.android.window.flags.Flags;
diff --git a/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java b/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java
index fa2d9bf..c0dc424 100644
--- a/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java
+++ b/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java
@@ -40,7 +40,7 @@
import android.window.TrustedPresentationThresholds;
import android.window.WindowInfosListener;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.wm.utils.RegionUtils;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
index 4a5a20e..fffe692 100644
--- a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
@@ -27,7 +27,7 @@
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 86440ac..2652670 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.app.WallpaperManager.COMMAND_DISPLAY_SWITCH;
import static android.app.WallpaperManager.COMMAND_FREEZE;
import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -57,7 +56,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils;
import com.android.window.flags.Flags;
@@ -119,11 +118,6 @@
private boolean mShouldOffsetWallpaperCenter;
- /**
- * Whether the wallpaper has been notified about a physical display switch event is started.
- */
- private volatile boolean mIsWallpaperNotifiedOnDisplaySwitch;
-
private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {
final boolean useShellTransition = w.mTransitionController.isShellTransitionsEnabled();
if (!useShellTransition) {
@@ -335,13 +329,13 @@
}
for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
final WallpaperWindowToken token = mWallpaperTokens.get(i);
- token.setVisibility(false);
if (token.isVisible()) {
ProtoLog.d(WM_DEBUG_WALLPAPER,
"Hiding wallpaper %s from %s target=%s prev=%s callers=%s",
token, winGoingAway, mWallpaperTarget, mPrevWallpaperTarget,
Debug.getCallers(5));
}
+ token.setVisibility(false);
}
}
@@ -1094,52 +1088,6 @@
}
/**
- * Notifies the wallpaper that the display turns off when switching physical device. If the
- * wallpaper is currently visible, its client visibility will be preserved until the display is
- * confirmed to be off or on.
- */
- void onDisplaySwitchStarted() {
- mIsWallpaperNotifiedOnDisplaySwitch = notifyDisplaySwitch(true /* start */);
- }
-
- /**
- * Called when the screen has finished turning on or the device goes to sleep. This is no-op if
- * the operation is not part of a display switch.
- */
- void onDisplaySwitchFinished() {
- // The method can be called outside WM lock (turned on), so only acquire lock if needed.
- // This is to optimize the common cases that regular devices don't have display switch.
- if (mIsWallpaperNotifiedOnDisplaySwitch) {
- synchronized (mService.mGlobalLock) {
- mIsWallpaperNotifiedOnDisplaySwitch = false;
- notifyDisplaySwitch(false /* start */);
- }
- }
- }
-
- private boolean notifyDisplaySwitch(boolean start) {
- boolean notified = false;
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
- for (int i = token.getChildCount() - 1; i >= 0; i--) {
- final WindowState w = token.getChildAt(i);
- if (start && !w.mWinAnimator.getShown()) {
- continue;
- }
- try {
- w.mClient.dispatchWallpaperCommand(COMMAND_DISPLAY_SWITCH, 0 /* x */, 0 /* y */,
- start ? 1 : 0 /* use z as start or finish */,
- null /* bundle */, false /* sync */);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to dispatch COMMAND_DISPLAY_SWITCH " + e);
- }
- notified = true;
- }
- }
- return notified;
- }
-
- /**
* Each window can request a zoom, example:
* - User is in overview, zoomed out.
* - User also pulls down the shade.
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 9d1551c..31156de 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -31,7 +31,8 @@
import android.os.RemoteException;
import android.util.SparseArray;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
import java.util.function.Consumer;
@@ -80,6 +81,20 @@
mDisplayContent.mWallpaperController.removeWallpaperToken(this);
}
+ @Override
+ public void prepareSurfaces() {
+ super.prepareSurfaces();
+
+ if (Flags.ensureWallpaperInTransitions()) {
+ // Similar to Task.prepareSurfaces, outside of transitions we need to apply visibility
+ // changes directly. In transitions the transition player will take care of applying the
+ // visibility change.
+ if (!mTransitionController.inTransition(this)) {
+ getSyncTransaction().setVisibility(mSurfaceControl, isVisible());
+ }
+ }
+ }
+
/**
* Controls whether this wallpaper shows underneath the keyguard or is hidden and only
* revealed once keyguard is dismissed.
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 8afcf0e..03342d3 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -34,7 +34,7 @@
import android.view.Choreographer;
import android.view.SurfaceControl;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 1f31af6..edd118d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -111,7 +111,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.wm.SurfaceAnimator.Animatable;
import com.android.server.wm.SurfaceAnimator.AnimationType;
@@ -237,12 +237,6 @@
/** Total number of elements in this subtree, including our own hierarchy element. */
private int mTreeWeight = 1;
- /**
- * Indicates whether we are animating and have committed the transaction to reparent our
- * surface to the animation leash
- */
- private boolean mCommittedReparentToAnimationLeash;
-
private int mSyncTransactionCommitCallbackDepth = 0;
/** Interface for {@link #isAnimating} to check which cases for the container is animating. */
@@ -2871,23 +2865,12 @@
}
void prepareSurfaces() {
- // If a leash has been set when the transaction was committed, then the leash reparent has
- // been committed.
- mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
for (int i = 0; i < mChildren.size(); i++) {
mChildren.get(i).prepareSurfaces();
}
}
/**
- * @return true if the reparent to animation leash transaction has been committed, false
- * otherwise.
- */
- boolean hasCommittedReparentToAnimationLeash() {
- return mCommittedReparentToAnimationLeash;
- }
-
- /**
* Trigger a call to prepareSurfaces from the animation thread, such that pending transactions
* will be applied.
*/
diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index b000a98..57fc4c7 100644
--- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -39,7 +39,7 @@
import android.view.SurfaceControl.Transaction;
import android.view.animation.Animation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.wm.SurfaceAnimator.Animatable;
import com.android.server.wm.SurfaceAnimator.AnimationType;
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 21f251f..cd785e5 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -39,7 +39,7 @@
import android.window.WindowContext;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.util.Objects;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 72ec058..57b8040 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -335,7 +335,7 @@
import com.android.internal.policy.KeyInterceptionInfo;
import com.android.internal.protolog.LegacyProtoLogImpl;
import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
@@ -3743,6 +3743,8 @@
null /* trigger */, null /* remote */, null /* disp */);
}
mCurrentUserId = newUserId;
+ mDisplayWindowSettingsProvider.setOverrideSettingsForUser(newUserId);
+ mDisplayWindowSettingsProvider.removeStaleDisplaySettings(mRoot);
mPolicy.setCurrentUserLw(newUserId);
mKeyguardDisableHandler.setCurrentUser(newUserId);
@@ -3796,7 +3798,7 @@
hideBootMessagesLocked();
// If the screen still doesn't come up after 30 seconds, give
// up and turn it on.
- mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000);
+ mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000 * Build.HW_TIMEOUT_MULTIPLIER);
}
mPolicy.systemBooted();
@@ -5479,6 +5481,9 @@
// DisplayWindowSettings are applied. In addition, wide-color/hdr/isTouchDevice also
// affect the Configuration.
mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);
+ // Per-user display settings may leave outdated settings after user switches, especially
+ // during reboots starting with the default user without setCurrentUser called.
+ mDisplayWindowSettingsProvider.removeStaleDisplaySettings(mRoot);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 1f06bfa..6febe80 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -51,7 +51,7 @@
import com.android.internal.protolog.LegacyProtoLogImpl;
import com.android.internal.protolog.PerfettoProtoLogImpl;
import com.android.internal.protolog.common.IProtoLog;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.IoThread;
import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition;
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index d26df7a..3431154 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -124,7 +124,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.pm.LauncherAppsService.LauncherAppsServiceInternal;
@@ -617,7 +617,7 @@
if (transition.isCollecting()) {
deferTransitionReady = true;
transition.deferTransitionReady();
- } else if (Flags.alwaysDeferTransitionWhenApplyWct()) {
+ } else {
Slog.w(TAG, "Transition is not collecting when applyTransaction."
+ " transition=" + transition + " state=" + transition.getState());
transition = null;
@@ -1105,6 +1105,7 @@
break;
}
if (activity.isVisible() || activity.isVisibleRequested()) {
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
// Prevent the transition from being executed too early if the activity is
// visible.
activity.finishIfPossible("finish-activity-op", false /* oomAdj */);
@@ -1122,6 +1123,7 @@
launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
final SafeActivityOptions safeOptions =
SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid);
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents(
caller.mPid, caller.mUid, taskId, safeOptions));
break;
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index b878072..60d3e78 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -82,7 +82,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.HeavyWeightSwitcherActivity;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.Watchdog;
import com.android.server.grammaticalinflection.GrammaticalInflectionManagerInternal;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f72e82a..fec1175 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -250,7 +250,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.KeyInterceptionInfo;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.policy.WindowManagerPolicy;
@@ -3695,7 +3695,7 @@
void fillInsetsSourceControls(@NonNull InsetsSourceControl.Array outArray,
boolean copyControls) {
- final int lastSeq = mLastReportedInsetsState.getSeq();
+ final int lastSeq = mLastReportedActiveControls.getSeq();
final InsetsSourceControl[] controls =
getDisplayContent().getInsetsStateController().getControlsForDispatch(this);
outArray.set(controls, copyControls);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 6fd7aa0..397a6357 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -62,7 +62,8 @@
import android.view.animation.AnimationUtils;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
@@ -374,9 +375,13 @@
ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s",
mWin, new RuntimeException().fillInStackTrace());
destroySurface(t);
- // Don't hide wallpaper if we're deferring the surface destroy
- // because of a surface change.
- mWallpaperControllerLocked.hideWallpapers(mWin);
+ if (Flags.ensureWallpaperInTransitions()) {
+ if (mWallpaperControllerLocked.isWallpaperTarget(mWin)) {
+ mWin.requestUpdateWallpaperIfNeeded();
+ }
+ } else {
+ mWallpaperControllerLocked.hideWallpapers(mWin);
+ }
} catch (RuntimeException e) {
Slog.w(TAG, "Exception thrown when destroying Window " + this
+ " surface " + mSurfaceController + " session " + mSession + ": "
@@ -431,7 +436,9 @@
if (!w.isOnScreen()) {
hide(t, "prepareSurfaceLocked");
- mWallpaperControllerLocked.hideWallpapers(w);
+ if (!w.mIsWallpaper || !Flags.ensureWallpaperInTransitions()) {
+ mWallpaperControllerLocked.hideWallpapers(w);
+ }
// If we are waiting for this window to handle an orientation change. If this window is
// really hidden (gone for layout), there is no point in still waiting for it.
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 4456a94..d9766e0 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -36,7 +36,7 @@
import android.view.SurfaceControl;
import android.view.WindowContentFrameStats;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 4dca23b..11ef2cd 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -47,7 +47,7 @@
import android.view.WindowManager.LayoutParams.WindowType;
import android.window.WindowContext;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index b0e71bd..ba5323e 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -37,7 +37,7 @@
import com.android.internal.protolog.LegacyProtoLogImpl;
import com.android.internal.protolog.common.IProtoLog;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.TraceBuffer;
import java.io.File;
diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
index 50d48b7..5c4db24 100644
--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp
+++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
@@ -45,6 +45,7 @@
TOUCHSCREEN,
DPAD,
STYLUS,
+ ROTARY_ENCODER,
};
static unique_fd invalidFd() {
@@ -114,6 +115,10 @@
ioctl(fd, UI_SET_ABSBIT, ABS_PRESSURE);
ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);
break;
+ case DeviceType::ROTARY_ENCODER:
+ ioctl(fd, UI_SET_EVBIT, EV_REL);
+ ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
+ break;
default:
ALOGE("Invalid input device type %d", static_cast<int32_t>(deviceType));
return invalidFd();
@@ -312,6 +317,13 @@
return fd.ok() ? reinterpret_cast<jlong>(new VirtualStylus(std::move(fd))) : INVALID_PTR;
}
+static jlong nativeOpenUinputRotaryEncoder(JNIEnv* env, jobject thiz, jstring name, jint vendorId,
+ jint productId, jstring phys, jint height, jint width) {
+ auto fd = openUinputJni(env, name, vendorId, productId, phys, DeviceType::ROTARY_ENCODER,
+ /* screenHeight= */ 0, /* screenWidth= */ 0);
+ return fd.ok() ? reinterpret_cast<jlong>(new VirtualRotaryEncoder(std::move(fd))) : INVALID_PTR;
+}
+
static void nativeCloseUinput(JNIEnv* env, jobject thiz, jlong ptr) {
VirtualInputDevice* virtualInputDevice = reinterpret_cast<VirtualInputDevice*>(ptr);
delete virtualInputDevice;
@@ -381,6 +393,13 @@
std::chrono::nanoseconds(eventTimeNanos));
}
+static bool nativeWriteRotaryEncoderScrollEvent(JNIEnv* env, jobject thiz, jlong ptr,
+ jfloat scrollAmount, jlong eventTimeNanos) {
+ VirtualRotaryEncoder* virtualRotaryEncoder = reinterpret_cast<VirtualRotaryEncoder*>(ptr);
+ return virtualRotaryEncoder->writeScrollEvent(scrollAmount,
+ std::chrono::nanoseconds(eventTimeNanos));
+}
+
static JNINativeMethod methods[] = {
{"nativeOpenUinputDpad", "(Ljava/lang/String;IILjava/lang/String;)J",
(void*)nativeOpenUinputDpad},
@@ -392,6 +411,8 @@
(void*)nativeOpenUinputTouchscreen},
{"nativeOpenUinputStylus", "(Ljava/lang/String;IILjava/lang/String;II)J",
(void*)nativeOpenUinputStylus},
+ {"nativeOpenUinputRotaryEncoder", "(Ljava/lang/String;IILjava/lang/String;)J",
+ (void*)nativeOpenUinputRotaryEncoder},
{"nativeCloseUinput", "(J)V", (void*)nativeCloseUinput},
{"nativeWriteDpadKeyEvent", "(JIIJ)Z", (void*)nativeWriteDpadKeyEvent},
{"nativeWriteKeyEvent", "(JIIJ)Z", (void*)nativeWriteKeyEvent},
@@ -401,6 +422,8 @@
{"nativeWriteScrollEvent", "(JFFJ)Z", (void*)nativeWriteScrollEvent},
{"nativeWriteStylusMotionEvent", "(JIIIIIIIJ)Z", (void*)nativeWriteStylusMotionEvent},
{"nativeWriteStylusButtonEvent", "(JIIJ)Z", (void*)nativeWriteStylusButtonEvent},
+ {"nativeWriteRotaryEncoderScrollEvent", "(JFJ)Z",
+ (void*)nativeWriteRotaryEncoderScrollEvent},
};
int register_android_server_companion_virtual_InputController(JNIEnv* env) {
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index bb0838d..7ed23cd 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -230,18 +230,7 @@
}
val isSoftRestricted =
if (permission.isSoftRestricted && !isExempt) {
- val targetSdkVersion =
- reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT) {
- targetSdkVersion,
- packageState ->
- if (permissionName in packageState.androidPackage!!.requestedPermissions) {
- targetSdkVersion.coerceAtMost(
- packageState.androidPackage!!.targetSdkVersion
- )
- } else {
- targetSdkVersion
- }
- }
+ val targetSdkVersion = getAppIdTargetSdkVersion(appId, permissionName)
!anyPackageInAppId(appId) {
permissionName in it.androidPackage!!.requestedPermissions &&
isSoftRestrictedPermissionExemptForPackage(
@@ -718,18 +707,8 @@
// If the app is updated, and has scoped storage permissions, then it is possible that the
// app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
- val oldTargetSdkVersion =
- reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT, oldState) {
- targetSdkVersion,
- packageState ->
- targetSdkVersion.coerceAtMost(packageState.androidPackage!!.targetSdkVersion)
- }
- val newTargetSdkVersion =
- reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT, newState) {
- targetSdkVersion,
- packageState ->
- targetSdkVersion.coerceAtMost(packageState.androidPackage!!.targetSdkVersion)
- }
+ val oldTargetSdkVersion = getAppIdTargetSdkVersion(appId, null, oldState)
+ val newTargetSdkVersion = getAppIdTargetSdkVersion(appId, null, newState)
@Suppress("ConvertTwoComparisonsToRangeCheck")
val isTargetSdkVersionDowngraded =
oldTargetSdkVersion >= Build.VERSION_CODES.Q &&
@@ -1115,6 +1094,7 @@
}
private fun MutateStateScope.inheritImplicitPermissionStates(appId: Int, userId: Int) {
+ val targetSdkVersion = getAppIdTargetSdkVersion(appId, null)
val implicitPermissions = MutableIndexedSet<String>()
forEachPackageInAppId(appId) {
implicitPermissions += it.androidPackage!!.implicitPermissions
@@ -1153,7 +1133,10 @@
newFlags = newFlags or (sourceFlags and PermissionFlags.MASK_RUNTIME)
}
}
- if (implicitPermissionName in RETAIN_IMPLICIT_FLAGS_PERMISSIONS) {
+ if (
+ targetSdkVersion >= Build.VERSION_CODES.M &&
+ implicitPermissionName in NO_IMPLICIT_FLAG_PERMISSIONS
+ ) {
newFlags = newFlags andInv PermissionFlags.IMPLICIT
} else {
newFlags = newFlags or PermissionFlags.IMPLICIT
@@ -1413,6 +1396,22 @@
else -> false
}
+ private fun MutateStateScope.getAppIdTargetSdkVersion(
+ appId: Int,
+ permissionName: String?,
+ state: AccessState = newState
+ ): Int =
+ reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT, state) {
+ targetSdkVersion,
+ packageState ->
+ val androidPackage = packageState.androidPackage!!
+ if (permissionName == null || permissionName in androidPackage.requestedPermissions) {
+ targetSdkVersion.coerceAtMost(androidPackage.targetSdkVersion)
+ } else {
+ targetSdkVersion
+ }
+ }
+
private inline fun MutateStateScope.anyPackageInAppId(
appId: Int,
state: AccessState = newState,
@@ -1782,7 +1781,7 @@
private const val PLATFORM_PACKAGE_NAME = "android"
// A set of permissions that we don't want to revoke when they are no longer implicit.
- private val RETAIN_IMPLICIT_FLAGS_PERMISSIONS =
+ private val NO_IMPLICIT_FLAG_PERMISSIONS =
indexedSetOf(
Manifest.permission.ACCESS_MEDIA_LOCATION,
Manifest.permission.ACTIVITY_RECOGNITION,
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
index d4adba2..9e46f2f 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
@@ -37,6 +37,7 @@
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import static java.util.Objects.requireNonNull;
@@ -50,6 +51,7 @@
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.inputmethod.InputBindResult;
+import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
@@ -73,9 +75,8 @@
@Before
public void setUp() throws RemoteException {
super.setUp();
- mVisibilityApplier =
- (DefaultImeVisibilityApplier) mInputMethodManagerService.getVisibilityApplier();
synchronized (ImfLock.class) {
+ mVisibilityApplier = mInputMethodManagerService.getVisibilityApplierLocked();
mUserId = mInputMethodManagerService.getCurrentImeUserIdLocked();
mInputMethodManagerService.setAttachedClientForTesting(requireNonNull(
mInputMethodManagerService.getClientStateLocked(mMockInputMethodClient)));
@@ -106,7 +107,7 @@
assertThrows(IllegalArgumentException.class, () -> {
synchronized (ImfLock.class) {
mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
- STATE_INVALID, mUserId);
+ STATE_INVALID, eq(SoftInputShowHideReason.NOT_SET), mUserId);
}
});
}
@@ -116,7 +117,7 @@
final var statsToken = ImeTracker.Token.empty();
synchronized (ImfLock.class) {
mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_SHOW_IME,
- mUserId);
+ eq(SoftInputShowHideReason.NOT_SET), mUserId);
}
verify(mMockWindowManagerInternal).showImePostLayout(eq(mWindowToken), eq(statsToken));
}
@@ -126,7 +127,7 @@
final var statsToken = ImeTracker.Token.empty();
synchronized (ImfLock.class) {
mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME,
- mUserId);
+ eq(SoftInputShowHideReason.NOT_SET), mUserId);
}
verify(mMockWindowManagerInternal).hideIme(eq(mWindowToken), anyInt() /* displayId */,
eq(statsToken));
@@ -134,20 +135,24 @@
@Test
public void testApplyImeVisibility_hideImeExplicit() throws Exception {
- mInputMethodManagerService.mImeWindowVis = IME_ACTIVE;
synchronized (ImfLock.class) {
+ final var bindingController =
+ mInputMethodManagerService.getInputMethodBindingController(mUserId);
+ when(bindingController.getImeWindowVis()).thenReturn(IME_ACTIVE);
mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
- STATE_HIDE_IME_EXPLICIT, mUserId);
+ STATE_HIDE_IME_EXPLICIT, eq(SoftInputShowHideReason.NOT_SET), mUserId);
}
verifyHideSoftInput(true, true);
}
@Test
public void testApplyImeVisibility_hideNotAlways() throws Exception {
- mInputMethodManagerService.mImeWindowVis = IME_ACTIVE;
synchronized (ImfLock.class) {
+ final var bindingController =
+ mInputMethodManagerService.getInputMethodBindingController(mUserId);
+ when(bindingController.getImeWindowVis()).thenReturn(IME_ACTIVE);
mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
- STATE_HIDE_IME_NOT_ALWAYS, mUserId);
+ STATE_HIDE_IME_NOT_ALWAYS, eq(SoftInputShowHideReason.NOT_SET), mUserId);
}
verifyHideSoftInput(true, true);
}
@@ -156,7 +161,7 @@
public void testApplyImeVisibility_showImeImplicit() throws Exception {
synchronized (ImfLock.class) {
mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
- STATE_SHOW_IME_IMPLICIT, mUserId);
+ STATE_SHOW_IME_IMPLICIT, eq(SoftInputShowHideReason.NOT_SET), mUserId);
}
verifyShowSoftInput(true, true, 0 /* showFlags */);
}
@@ -177,7 +182,7 @@
// Verify hideIme will apply the expected displayId when the default IME
// visibility applier app STATE_HIDE_IME.
mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME,
- mUserId);
+ eq(SoftInputShowHideReason.NOT_SET), mUserId);
verify(mInputMethodManagerService.mWindowManagerInternal).hideIme(
eq(mWindowToken), eq(displayIdToShowIme), eq(statsToken));
}
@@ -217,14 +222,15 @@
final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
mInputMethodManagerService.hideCurrentInputLocked(mWindowToken,
statsToken, 0 /* flags */, null /* resultReceiver */,
- HIDE_SWITCH_USER);
- mInputMethodManagerService.onUnbindCurrentMethodByReset();
+ HIDE_SWITCH_USER, mUserId);
+ mInputMethodManagerService.onUnbindCurrentMethodByReset(mUserId);
// Expects applyImeVisibility() -> hideIme() will be called to notify WM for syncing
// the IME hidden state.
// The unbind will cancel the previous stats token, and create a new one internally.
verify(mVisibilityApplier).applyImeVisibility(
- eq(mWindowToken), any(), eq(STATE_HIDE_IME), eq(mUserId) /* userId */);
+ eq(mWindowToken), any(), eq(STATE_HIDE_IME),
+ eq(SoftInputShowHideReason.NOT_SET), eq(mUserId) /* userId */);
verify(mInputMethodManagerService.mWindowManagerInternal).hideIme(
eq(mWindowToken), eq(displayIdToShowIme), and(not(eq(statsToken)), notNull()));
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
index a22cacb..337d5c1 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
@@ -58,8 +58,8 @@
import org.mockito.ArgumentCaptor;
/**
- * Test the behavior of {@link ImeVisibilityStateComputer} and {@link ImeVisibilityApplier} when
- * requesting the IME visibility.
+ * Test the behavior of {@link ImeVisibilityStateComputer} and {@link DefaultImeVisibilityApplier}
+ * when requesting the IME visibility.
*
* <p> Build/Install/Run:
* atest FrameworksInputMethodSystemServerTests:ImeVisibilityStateComputerTest
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
index 70903cb..4d28b3c 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
@@ -140,7 +140,8 @@
final InputMethodInfo info;
synchronized (ImfLock.class) {
mBindingController.setSelectedMethodId(TEST_IME_ID);
- info = mInputMethodManagerService.queryInputMethodForCurrentUserLocked(TEST_IME_ID);
+ info = InputMethodSettingsRepository.get(mCallingUserId).getMethodMap()
+ .get(TEST_IME_ID);
}
assertThat(info).isNotNull();
assertThat(info.getId()).isEqualTo(TEST_IME_ID);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
index 42bd75a..80eab11 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
@@ -189,6 +189,7 @@
// Injecting and mocked InputMethodBindingController and InputMethod.
mMockInputMethodInvoker = IInputMethodInvoker.create(mMockInputMethod);
mInputManagerGlobalSession = InputManagerGlobal.createTestSession(mMockIInputManager);
+ when(mMockInputMethodBindingController.getUserId()).thenReturn(mCallingUserId);
synchronized (ImfLock.class) {
when(mMockInputMethodBindingController.getCurMethod())
.thenReturn(mMockInputMethodInvoker);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
index f9f45057..e2f3eec 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
@@ -106,7 +106,7 @@
// Assert UserDataRepository called the InputMethodBindingController creator function.
verify(bindingControllerFactorySpy).apply(ANY_USER_ID);
- assertThat(allUserData.get(0).mBindingController.mUserId).isEqualTo(ANY_USER_ID);
+ assertThat(allUserData.get(0).mBindingController.getUserId()).isEqualTo(ANY_USER_ID);
}
@Test
@@ -149,7 +149,7 @@
assertThat(allUserData.get(0).mUserId).isEqualTo(ANY_USER_ID);
// Assert UserDataRepository called the InputMethodBindingController creator function.
- assertThat(allUserData.get(0).mBindingController.mUserId).isEqualTo(ANY_USER_ID);
+ assertThat(allUserData.get(0).mBindingController.getUserId()).isEqualTo(ANY_USER_ID);
}
private List<UserDataRepository.UserData> collectUserData(UserDataRepository repository) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 211ab03..d268637 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -2584,18 +2584,19 @@
LogicalDisplay display =
logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true);
+ displayManager.setDisplayState(display.getDisplayIdLocked(), Display.STATE_ON);
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
- assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), false))
- .isTrue();
+ assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+ Display.STATE_OFF)).isTrue();
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_OFF);
- assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), true))
- .isTrue();
+ assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+ Display.STATE_UNKNOWN)).isTrue();
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
@@ -2621,8 +2622,10 @@
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
- assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, true));
- assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, false));
+ assertThrows(SecurityException.class,
+ () -> bs.requestDisplayPower(displayId, Display.STATE_UNKNOWN));
+ assertThrows(SecurityException.class,
+ () -> bs.requestDisplayPower(displayId, Display.STATE_OFF));
}
@Test
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index bb774ee..d070aaa 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -1700,14 +1700,17 @@
verify(mDisplayOffloadSession, never()).cancelBlockScreenOn();
}
- @RequiresFlagsEnabled(Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON)
@Test
public void testOffloadBlocker_turnON_thenOFF_cancelBlockScreenOnNotCalledIfUnblocked() {
// Set up.
+ when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.isOffloadSessionCancelBlockScreenOnEnabled())
+ .thenReturn(true);
int initState = Display.STATE_OFF;
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
- when(mDisplayOffloadSession.blockScreenOn(any())).thenReturn(true);
+ ArgumentCaptor<Runnable> argumentCaptor = ArgumentCaptor.forClass(Runnable.class);
+ when(mDisplayOffloadSession.blockScreenOn(argumentCaptor.capture())).thenReturn(true);
// Start with OFF.
when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
@@ -1721,8 +1724,7 @@
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
- ArgumentCaptor<Runnable> argumentCaptor = ArgumentCaptor.forClass(Runnable.class);
- verify(mDisplayOffloadSession).blockScreenOn(argumentCaptor.capture());
+ verify(mDisplayOffloadSession).blockScreenOn(any());
// Unblocked
argumentCaptor.getValue().run();
@@ -1737,10 +1739,12 @@
verify(mDisplayOffloadSession, never()).cancelBlockScreenOn();
}
- @RequiresFlagsEnabled(Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON)
@Test
public void testOffloadBlocker_turnON_thenOFF_cancelBlockScreenOn() {
// Set up.
+ when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.isOffloadSessionCancelBlockScreenOnEnabled())
+ .thenReturn(true);
int initState = Display.STATE_OFF;
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
diff --git a/services/tests/dreamservicetests/AndroidManifest.xml b/services/tests/dreamservicetests/AndroidManifest.xml
index 6092ef6..449521b 100644
--- a/services/tests/dreamservicetests/AndroidManifest.xml
+++ b/services/tests/dreamservicetests/AndroidManifest.xml
@@ -53,6 +53,35 @@
android:name="android.service.dream"
android:resource="@xml/test_dream_metadata_invalid" />
</service>
+
+ <service
+ android:name="com.android.server.dreams.TestDreamServiceWithNonexistentSettings"
+ android:exported="false"
+ android:label="Test Dream" >
+ <intent-filter>
+ <action android:name="android.service.dreams.DreamService" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data
+ android:name="android.service.dream"
+ android:resource="@xml/test_dream_metadata_nonexistent_settings" />
+ </service>
+
+ <service
+ android:name="com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings"
+ android:exported="false"
+ android:label="Test Dream" >
+ <intent-filter>
+ <action android:name="android.service.dreams.DreamService" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data
+ android:name="android.service.dream"
+ android:resource="@xml/test_dream_metadata_nopackage_nonexistent_settings" />
+ </service>
+
+ <activity android:name=".TestDreamSettingsActivity">
+ </activity>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml
new file mode 100644
index 0000000..f91f058
--- /dev/null
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<!-- The settings activity does not exist, which is invalid. -->
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+ android:settingsActivity="com.android.frameworks.dreamservicetests/.TestDreamSettingsActivityNonexistent"
+ android:showClockAndComplications="false"/>
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml
new file mode 100644
index 0000000..24032c9
--- /dev/null
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<!-- The settings activity's ComponentName is invalid. -->
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+ android:settingsActivity="com.android.frameworks.dreamservicetests.TestDreamSettingsActivityNonexistentNoPackage"
+ android:showClockAndComplications="false"/>
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index b98af6b..b4e1abf 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -91,6 +91,28 @@
}
@Test
+ public void testMetadataParsing_nonexistentSettingsActivity()
+ throws PackageManager.NameNotFoundException {
+ final String testDreamClassName =
+ "com.android.server.dreams.TestDreamServiceWithNonexistentSettings";
+ final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
+
+ assertThat(metadata.settingsActivity).isNull();
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
+ }
+
+ @Test
+ public void testMetadataParsing_noPackage_nonexistentSettingsActivity()
+ throws PackageManager.NameNotFoundException {
+ final String testDreamClassName =
+ "com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings";
+ final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
+
+ assertThat(metadata.settingsActivity).isNull();
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
+ }
+
+ @Test
public void testMetadataParsing_exceptionReading() {
final PackageManager packageManager = Mockito.mock(PackageManager.class);
final ServiceInfo serviceInfo = Mockito.mock(ServiceInfo.class);
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java
new file mode 100644
index 0000000..bb8db8a
--- /dev/null
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2024 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.dreams;
+
+public class TestDreamSettingsActivity {
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 42814e7..3377899 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -74,7 +74,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -227,9 +226,6 @@
setCrashRecoveryPropRescueBootCount(0);
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false));
-
- // enable flag resets for tests
- mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_RESCUE_PARTY_FLAG_RESETS);
}
@After
@@ -250,9 +246,6 @@
noteBoot(1);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
- verifiedTimesMap);
-
// Record DeviceConfig accesses
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
@@ -262,15 +255,8 @@
final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
noteBoot(2);
-
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedAllResetNamespaces,
- verifiedTimesMap);
-
noteBoot(3);
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
- verifiedTimesMap);
-
noteBoot(4);
assertTrue(RescueParty.isRebootPropertySet());
@@ -296,7 +282,6 @@
final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
noteBoot(1);
- verifyDeviceConfigReset(expectedAllResetNamespaces, verifiedTimesMap);
noteBoot(2);
assertTrue(RescueParty.isRebootPropertySet());
@@ -321,20 +306,9 @@
mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
noteAppCrash(1, true);
-
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
- /*configResetVerifiedTimesMap=*/ null);
-
noteAppCrash(2, true);
-
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null,
- /*configResetVerifiedTimesMap=*/ null);
-
noteAppCrash(3, true);
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
- /*configResetVerifiedTimesMap=*/ null);
-
noteAppCrash(4, true);
assertTrue(RescueParty.isRebootPropertySet());
@@ -362,10 +336,8 @@
final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
noteAppCrash(1, true);
- verifyDeviceConfigReset(expectedResetNamespaces, verifiedTimesMap);
noteAppCrash(2, true);
- verifyDeviceConfigReset(expectedAllResetNamespaces, verifiedTimesMap);
noteAppCrash(3, true);
assertTrue(RescueParty.isRebootPropertySet());
@@ -385,26 +357,13 @@
}
@Test
- public void testNonPersistentAppOnlyPerformsFlagResets() {
+ public void testNonPersistentAppDoesntDoAnything() {
// this is old test where the flag needs to be disabled
mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
noteAppCrash(1, false);
-
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
- /*configResetVerifiedTimesMap=*/ null);
-
noteAppCrash(2, false);
-
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null,
- /*configResetVerifiedTimesMap=*/ null);
-
noteAppCrash(3, false);
-
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
- /*configResetVerifiedTimesMap=*/ null);
-
- noteAppCrash(4, false);
assertFalse(RescueParty.isRebootPropertySet());
noteAppCrash(5, false);
@@ -430,10 +389,8 @@
final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
noteAppCrash(1, false);
- verifyDeviceConfigReset(expectedResetNamespaces, verifiedTimesMap);
noteAppCrash(2, false);
- verifyDeviceConfigReset(expectedAllResetNamespaces, verifiedTimesMap);
noteAppCrash(3, false);
assertFalse(RescueParty.isRebootPropertySet());
@@ -488,87 +445,12 @@
HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, expectedResetNamespaces,
- verifiedTimesMap);
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedResetNamespaces,
- verifiedTimesMap);
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
- verifiedTimesMap);
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4);
- assertFalse(RescueParty.isRebootPropertySet());
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 5);
- assertFalse(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
- public void testNonDeviceConfigSettingsOnlyResetOncePerLevel() {
- // this is old test where the flag needs to be disabled
- mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
-
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
-
- // Record DeviceConfig accesses
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3);
- // Fake DeviceConfig value changes
- monitorCallback.onNamespaceUpdate(NAMESPACE1);
- monitorCallback.onNamespaceUpdate(NAMESPACE2);
- monitorCallback.onNamespaceUpdate(NAMESPACE3);
- // Perform and verify scoped resets
- final String[] expectedPackage1ResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
- final String[] expectedPackage2ResetNamespaces = new String[]{NAMESPACE2, NAMESPACE3};
- final String[] expectedAllResetNamespaces =
- new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3};
- HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
- expectedPackage1ResetNamespaces, verifiedTimesMap);
-
- // Settings.Global & Settings.Secure should still remain the same execution times.
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE2, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
- expectedPackage2ResetNamespaces, verifiedTimesMap);
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES,
- expectedPackage1ResetNamespaces, verifiedTimesMap);
-
- // Settings.Global & Settings.Secure should still remain the same execution times.
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE2, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES,
- expectedPackage2ResetNamespaces, verifiedTimesMap);
-
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
- verifiedTimesMap);
-
- // Settings.Global & Settings.Secure should still remain the same execution times.
- observer.execute(new VersionedPackage(
- CALLING_PACKAGE2, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
- verifiedTimesMap);
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4);
@@ -863,27 +745,27 @@
assertEquals(observer.onHealthCheckFailed(sFailingPackage,
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_20);
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
assertEquals(observer.onHealthCheckFailed(sFailingPackage,
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_20);
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
assertEquals(observer.onHealthCheckFailed(sFailingPackage,
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_20);
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
assertEquals(observer.onHealthCheckFailed(sFailingPackage,
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 5),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_20);
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
assertEquals(observer.onHealthCheckFailed(sFailingPackage,
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 6),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_20);
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
assertEquals(observer.onHealthCheckFailed(sFailingPackage,
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 7),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_20);
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
}
@Test
@@ -906,7 +788,7 @@
mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
- assertEquals(observer.onBootLoop(1), PackageHealthObserverImpact.USER_IMPACT_LEVEL_20);
+ assertEquals(observer.onBootLoop(1), PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
assertEquals(observer.onBootLoop(2), PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
assertEquals(observer.onBootLoop(3), PackageHealthObserverImpact.USER_IMPACT_LEVEL_71);
assertEquals(observer.onBootLoop(4), PackageHealthObserverImpact.USER_IMPACT_LEVEL_75);
@@ -1037,7 +919,6 @@
private void verifySettingsResets(int resetMode, String[] resetNamespaces,
HashMap<String, Integer> configResetVerifiedTimesMap) {
verifyOnlySettingsReset(resetMode);
- verifyDeviceConfigReset(resetNamespaces, configResetVerifiedTimesMap);
}
private void verifyOnlySettingsReset(int resetMode) {
@@ -1054,26 +935,6 @@
eq(resetMode), anyInt()), never());
}
- private void verifyDeviceConfigReset(String[] resetNamespaces,
- Map<String, Integer> configResetVerifiedTimesMap) {
- if (resetNamespaces == null) {
- verify(() -> DeviceConfig.resetToDefaults(anyInt(), anyString()), never());
- } else {
- for (String namespace : resetNamespaces) {
- int verifiedTimes = 0;
- if (configResetVerifiedTimesMap != null
- && configResetVerifiedTimesMap.get(namespace) != null) {
- verifiedTimes = configResetVerifiedTimesMap.get(namespace);
- }
- verify(() -> DeviceConfig.resetToDefaults(RescueParty.DEVICE_CONFIG_RESET_MODE,
- namespace), times(verifiedTimes + 1));
- if (configResetVerifiedTimesMap != null) {
- configResetVerifiedTimesMap.put(namespace, verifiedTimes + 1);
- }
- }
- }
- }
-
private void noteBoot(int mitigationCount) {
RescuePartyObserver.getInstance(mMockContext).executeBootLoopMitigation(mitigationCount);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java
new file mode 100644
index 0000000..a82658b
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2024 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.pm;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.media.AudioAttributes;
+import android.media.AudioFocusInfo;
+import android.media.AudioManager;
+import android.os.Build;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.ArraySet;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(JUnit4.class)
+
+public class BackgroundUserSoundNotifierTest {
+ private final Context mRealContext = androidx.test.InstrumentationRegistry.getInstrumentation()
+ .getTargetContext();
+ private Context mSpiedContext;
+ private BackgroundUserSoundNotifier mBackgroundUserSoundNotifier;
+
+ private UserManager mUserManager;
+ private ArraySet<Integer> mUsersToRemove;
+
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mSpiedContext = spy(mRealContext);
+ mUsersToRemove = new ArraySet<>();
+ mUserManager = UserManager.get(mRealContext);
+ doReturn(mNotificationManager)
+ .when(mSpiedContext).getSystemService(NotificationManager.class);
+ mBackgroundUserSoundNotifier = new BackgroundUserSoundNotifier(mSpiedContext);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mUsersToRemove.stream().toList().forEach(this::removeUser);
+ }
+ @Test
+ public void testAlarmOnBackgroundUser_ForegroundUserNotified() throws RemoteException {
+ AudioAttributes aa = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_ALARM).build();
+ UserInfo user = createUser("User",
+ UserManager.USER_TYPE_FULL_SECONDARY,
+ 0);
+ final int fgUserId = mSpiedContext.getUserId();
+ final int bgUserUid = user.id * 100000;
+ doReturn(UserHandle.of(fgUserId)).when(mSpiedContext).getUser();
+ AudioFocusInfo afi = new AudioFocusInfo(aa, bgUserUid, "",
+ /* packageName= */ "com.android.car.audio", AudioManager.AUDIOFOCUS_GAIN,
+ AudioManager.AUDIOFOCUS_NONE, /* flags= */ 0, Build.VERSION.SDK_INT);
+ clearInvocations(mNotificationManager);
+ mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi, mSpiedContext);
+ verify(mNotificationManager)
+ .notifyAsUser(eq(BackgroundUserSoundNotifier.class.getSimpleName()),
+ eq(afi.getClientUid()), any(Notification.class),
+ eq(UserHandle.of(fgUserId)));
+ }
+
+ @Test
+ public void testMediaOnBackgroundUser_ForegroundUserNotNotified() throws RemoteException {
+ AudioAttributes aa = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA).build();
+ UserInfo user = createUser("User", UserManager.USER_TYPE_FULL_SECONDARY, 0);
+ final int bgUserUid = mSpiedContext.getUserId() * 100000;
+ AudioFocusInfo afi = new AudioFocusInfo(aa, bgUserUid, "",
+ /* packageName= */ "com.android.car.audio", AudioManager.AUDIOFOCUS_GAIN,
+ AudioManager.AUDIOFOCUS_NONE, /* flags= */ 0, Build.VERSION.SDK_INT);
+ clearInvocations(mNotificationManager);
+ mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi, mSpiedContext);
+ verifyZeroInteractions(mNotificationManager);
+ }
+
+ @Test
+ public void testAlarmOnForegroundUser_ForegroundUserNotNotified() throws RemoteException {
+ AudioAttributes aa = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_ALARM).build();
+ final int fgUserId = mSpiedContext.getUserId();
+ final int fgUserUid = fgUserId * 100000;
+ doReturn(UserHandle.of(fgUserId)).when(mSpiedContext).getUser();
+ AudioFocusInfo afi = new AudioFocusInfo(aa, fgUserUid, "", /* packageName= */ "",
+ AudioManager.AUDIOFOCUS_GAIN, AudioManager.AUDIOFOCUS_NONE, /* flags= */ 0,
+ Build.VERSION.SDK_INT);
+ clearInvocations(mNotificationManager);
+ mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi, mSpiedContext);
+ verifyZeroInteractions(mNotificationManager);
+ }
+
+
+ private UserInfo createUser(String name, String userType, int flags) {
+ UserInfo user = mUserManager.createUser(name, userType, flags);
+ if (user != null) {
+ mUsersToRemove.add(user.id);
+ }
+ return user;
+ }
+ private void removeUser(int userId) {
+ mUserManager.removeUser(userId);
+ }
+
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 79f1574..37d87c4e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -683,15 +683,14 @@
UserInfo privateProfileUser =
mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME,
USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null);
- Mockito.doNothing().when(mSpiedUms).scheduleMessageToAutoLockPrivateSpace(
- eq(privateProfileUser.getUserHandle().getIdentifier()), any(),
- anyLong());
+ Mockito.doNothing().when(mSpiedUms).scheduleAlarmToAutoLockPrivateSpace(
+ eq(privateProfileUser.getUserHandle().getIdentifier()), anyLong());
- mSpiedUms.maybeScheduleMessageToAutoLockPrivateSpace();
+ mSpiedUms.maybeScheduleAlarmToAutoLockPrivateSpace();
- Mockito.verify(mSpiedUms).scheduleMessageToAutoLockPrivateSpace(
- eq(privateProfileUser.getUserHandle().getIdentifier()), any(), anyLong());
+ Mockito.verify(mSpiedUms).scheduleAlarmToAutoLockPrivateSpace(
+ eq(privateProfileUser.getUserHandle().getIdentifier()), anyLong());
}
@Test
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
index 0275319..ef20946 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
@@ -39,6 +39,7 @@
import android.os.BatteryStats;
import android.os.Handler;
import android.os.OutcomeReceiver;
+import android.os.connectivity.CellularBatteryStats;
import android.platform.test.ravenwood.RavenwoodRule;
import android.telephony.AccessNetworkConstants;
import android.telephony.ActivityStatsTechSpecificInfo;
@@ -167,6 +168,7 @@
public void setup() {
MockitoAnnotations.initMocks(this);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephony);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)).thenReturn(true);
when(mPowerStatsUidResolver.mapUid(anyInt())).thenAnswer(invocation -> {
int uid = invocation.getArgument(0);
@@ -352,8 +354,48 @@
"UID 42: rx-pkts: 100 rx-B: 1000 tx-pkts: 200 tx-B: 2000");
}
+ @Test
+ public void getCellularBatteryStats() throws Throwable {
+ mBatteryStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
+ true);
+
+ mockModemActivityInfo(1000, 2000, 3000, 600, new int[]{100, 200, 300, 400, 500});
+ mockNetworkStats(1100,
+ 5321, 421, 3234, 223,
+ 8000, 80, 4000, 40);
+
+ // This should trigger a baseline sample collection
+ mBatteryStats.onSystemReady(mContext);
+ mStatsRule.waitForBackgroundThread();
+
+ mockModemActivityInfo(20000, 2222, 3333, 666, new int[]{111, 222, 333, 444, 555});
+ mockNetworkStats(21000,
+ 6321, 521, 7234, 423,
+ 8888, 88, 4444, 44);
+
+ mStatsRule.setTime(30000, 30000);
+ mBatteryStats.getPowerStatsCollector(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)
+ .schedule();
+ mStatsRule.waitForBackgroundThread();
+
+ CellularBatteryStats stats = mBatteryStats.getCellularBatteryStats();
+ assertThat(stats.getSleepTimeMillis()).isEqualTo(222);
+ assertThat(stats.getIdleTimeMillis()).isEqualTo(333);
+ assertThat(stats.getRxTimeMillis()).isEqualTo(66);
+ assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_0)).isEqualTo(11);
+ assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_1)).isEqualTo(22);
+ assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_2)).isEqualTo(33);
+ assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_3)).isEqualTo(44);
+ assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_4)).isEqualTo(55);
+ assertThat(stats.getNumPacketsRx()).isEqualTo(934);
+ assertThat(stats.getNumBytesRx()).isEqualTo(19967);
+ assertThat(stats.getNumPacketsTx()).isEqualTo(770);
+ assertThat(stats.getNumBytesTx()).isEqualTo(14214);
+ }
+
private PowerStats collectPowerStats(boolean perNetworkTypeData) throws Throwable {
- MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+ MobileRadioPowerStatsCollector collector =
+ new MobileRadioPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
when(mConsumedEnergyRetriever.getEnergyConsumerIds(
@@ -462,6 +504,7 @@
.addEntry(new NetworkStats.Entry("mobile", APP_UID3, 0, 0, METERED_NO,
ROAMING_NO, DEFAULT_NETWORK_NO, 314, 281, 314, 281, 111));
}
+ mBatteryStats.setNetworkStats(stats);
when(mNetworkStatsSupplier.get()).thenReturn(stats);
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java
index 137c2a6..d7024e5 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java
@@ -191,7 +191,8 @@
aggregatedStats.setUidState(APP_UID, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND, 0);
aggregatedStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0);
- MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+ MobileRadioPowerStatsCollector collector =
+ new MobileRadioPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
// Initial empty ModemActivityInfo.
@@ -430,7 +431,8 @@
aggregatedStats.setUidState(APP_UID, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND, 0);
aggregatedStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0);
- MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+ MobileRadioPowerStatsCollector collector =
+ new MobileRadioPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
// Initial empty ModemActivityInfo.
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java
index 548d54c..c268110 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java
@@ -180,7 +180,8 @@
aggregatedPowerStats.setDeviceState(STATE_POWER, POWER_STATE_OTHER, 0);
aggregatedPowerStats.setDeviceState(STATE_SCREEN, SCREEN_STATE_ON, 0);
- MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+ MobileRadioPowerStatsCollector collector =
+ new MobileRadioPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
// Initial empty ModemActivityInfo.
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
index a280cfe..362607b 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
@@ -40,6 +40,7 @@
import android.os.Handler;
import android.os.WorkSource;
import android.os.connectivity.WifiActivityEnergyInfo;
+import android.os.connectivity.WifiBatteryStats;
import android.platform.test.ravenwood.RavenwoodRule;
import android.util.IndentingPrintWriter;
import android.util.SparseArray;
@@ -186,6 +187,7 @@
return uid;
}
});
+ when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
mBatteryStats = mStatsRule.getBatteryStats();
}
@@ -319,10 +321,51 @@
+ " scan: 234 batched-scan: 345");
}
+ @Test
+ public void getWifiBatteryStats() throws Throwable {
+ when(mWifiManager.isEnhancedPowerReportingSupported()).thenReturn(true);
+ mBatteryStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_WIFI,
+ true);
+
+ mockWifiActivityInfo(1000, 600, 100, 2000, 3000);
+ mockNetworkStats(1000);
+ mockNetworkStatsEntry(APP_UID1, 4321, 321, 1234, 23);
+ mockNetworkStatsEntry(APP_UID2, 4000, 40, 2000, 20);
+ mockWifiScanTimes(APP_UID1, 1000, 2000);
+ mockWifiScanTimes(APP_UID2, 3000, 4000);
+
+ // This should trigger a baseline sample collection
+ mBatteryStats.onSystemReady(mContext);
+ mStatsRule.waitForBackgroundThread();
+
+ mockWifiActivityInfo(1100, 6600, 1100, 2200, 3300);
+ mockNetworkStats(1100);
+ mockNetworkStatsEntry(APP_UID1, 5321, 421, 3234, 223);
+ mockNetworkStatsEntry(APP_UID2, 8000, 80, 4000, 40);
+ mockWifiScanTimes(APP_UID1, 1234, 2345);
+ mockWifiScanTimes(APP_UID2, 3100, 4200);
+
+ mStatsRule.setTime(30000, 30000);
+ mBatteryStats.getPowerStatsCollector(BatteryConsumer.POWER_COMPONENT_WIFI)
+ .schedule();
+ mStatsRule.waitForBackgroundThread();
+
+ WifiBatteryStats stats = mBatteryStats.getWifiBatteryStats();
+ assertThat(stats.getNumPacketsRx()).isEqualTo(501);
+ assertThat(stats.getNumBytesRx()).isEqualTo(13321);
+ assertThat(stats.getNumPacketsTx()).isEqualTo(263);
+ assertThat(stats.getNumBytesTx()).isEqualTo(7234);
+ assertThat(stats.getScanTimeMillis()).isEqualTo(2200);
+ assertThat(stats.getRxTimeMillis()).isEqualTo(6000);
+ assertThat(stats.getTxTimeMillis()).isEqualTo(1000);
+ assertThat(stats.getIdleTimeMillis()).isEqualTo(300);
+ assertThat(stats.getSleepTimeMillis()).isEqualTo(30000 - 6000 - 1000 - 300);
+ }
+
private PowerStats collectPowerStats(boolean hasPowerReporting) {
when(mWifiManager.isEnhancedPowerReportingSupported()).thenReturn(hasPowerReporting);
- WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+ WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.WIFI))
@@ -389,6 +432,7 @@
} else {
mNetworkStats = new NetworkStats(elapsedRealtime, 1);
}
+ mBatteryStats.setNetworkStats(mNetworkStats);
when(mNetworkStatsSupplier.get()).thenReturn(mNetworkStats);
}
@@ -411,6 +455,7 @@
.addEntry(new NetworkStats.Entry("wifi", uid, 0, 0,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, rxBytes, rxPackets,
txBytes, txPackets, 100));
+ mBatteryStats.setNetworkStats(mNetworkStats);
reset(mNetworkStatsSupplier);
when(mNetworkStatsSupplier.get()).thenReturn(mNetworkStats);
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java
index ff56691..7ddaefd 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java
@@ -99,6 +99,8 @@
@Mock
private WifiManager mWifiManager;
+ private MockBatteryStatsImpl mBatteryStats;
+
private static class ScanTimes {
public long scanTimeMs;
public long batchScanTimeMs;
@@ -185,6 +187,8 @@
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
when(mPowerStatsUidResolver.mapUid(anyInt()))
.thenAnswer(invocation -> invocation.getArgument(0));
+
+ mBatteryStats = mStatsRule.getBatteryStats();
}
@Test
@@ -200,7 +204,7 @@
PowerComponentAggregatedPowerStats aggregatedStats = createAggregatedPowerStats(processor);
- WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+ WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
// Initial empty WifiActivityEnergyInfo.
@@ -312,7 +316,7 @@
PowerComponentAggregatedPowerStats aggregatedStats = createAggregatedPowerStats(processor);
- WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+ WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
// Initial empty WifiActivityEnergyInfo.
@@ -425,7 +429,7 @@
PowerComponentAggregatedPowerStats aggregatedStats = createAggregatedPowerStats(processor);
- WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+ WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
collector.setEnabled(true);
// Establish a baseline
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index a40bbd2..20b9592 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -27,6 +27,7 @@
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.server.accessibility.AccessibilityManagerService.ACTION_LAUNCH_HEARING_DEVICES_DIALOG;
import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER;
@@ -599,7 +600,7 @@
final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked());
- userState.mAccessibilityShortcutKeyTargets.add(MAGNIFICATION_CONTROLLER_NAME);
+ userState.updateShortcutTargetsLocked(Set.of(MAGNIFICATION_CONTROLLER_NAME), HARDWARE);
userState.setMagnificationCapabilitiesLocked(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
@@ -799,8 +800,8 @@
final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked());
mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);
- userState.mAccessibilityShortcutKeyTargets.add(
- ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+ userState.updateShortcutTargetsLocked(
+ Set.of(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString()), HARDWARE);
mA11yms.performAccessibilityShortcut(
Display.DEFAULT_DISPLAY, HARDWARE,
@@ -818,8 +819,8 @@
final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked());
mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);
- userState.mAccessibilityShortcutKeyTargets.add(
- ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+ userState.updateShortcutTargetsLocked(
+ Set.of(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString()), HARDWARE);
mA11yms.performAccessibilityShortcut(
Display.DEFAULT_DISPLAY, HARDWARE,
@@ -875,9 +876,10 @@
userState.mInstalledServices.clear();
userState.mInstalledServices.add(info_a);
userState.mInstalledServices.add(info_b);
- userState.mAccessibilityButtonTargets.clear();
- userState.mAccessibilityButtonTargets.add(info_a.getComponentName().flattenToString());
- userState.mAccessibilityButtonTargets.add(info_b.getComponentName().flattenToString());
+ userState.updateShortcutTargetsLocked(Set.of(
+ info_a.getComponentName().flattenToString(),
+ info_b.getComponentName().flattenToString()),
+ SOFTWARE);
// despite force stopping both packages, only the first service has the relevant flag,
// so only the first should be removed.
@@ -891,11 +893,11 @@
//Assert user state change
userState = mA11yms.getCurrentUserState();
- assertThat(userState.mAccessibilityButtonTargets).containsExactly(
+ assertThat(userState.getShortcutTargetsLocked(SOFTWARE)).containsExactly(
info_b.getComponentName().flattenToString());
//Assert setting change
final Set<String> targetsFromSetting = new ArraySet<>();
- mA11yms.readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+ mA11yms.readColonDelimitedSettingToSet(ShortcutUtils.convertToKey(SOFTWARE),
userState.mUserId, str -> str, targetsFromSetting);
assertThat(targetsFromSetting).containsExactly(info_b.getComponentName().flattenToString());
}
@@ -996,10 +998,10 @@
final AccessibilityServiceInfo info_c = mockAccessibilityServiceInfo(
new ComponentName("package_c", "class_c"));
final AccessibilityUserState userState = mA11yms.getCurrentUserState();
- userState.mAccessibilityButtonTargets.clear();
- userState.mAccessibilityButtonTargets.add(info_b.getComponentName().flattenToString());
- userState.mAccessibilityShortcutKeyTargets.clear();
- userState.mAccessibilityShortcutKeyTargets.add(info_c.getComponentName().flattenToString());
+ userState.updateShortcutTargetsLocked(
+ Set.of(info_b.getComponentName().flattenToString()), SOFTWARE);
+ userState.updateShortcutTargetsLocked(
+ Set.of(info_c.getComponentName().flattenToString()), HARDWARE);
assertThat(mA11yms.isAccessibilityServiceWarningRequired(info_a)).isTrue();
assertThat(mA11yms.isAccessibilityServiceWarningRequired(info_b)).isFalse();
@@ -1560,8 +1562,8 @@
mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);
setupShortcutTargetServices();
final AccessibilityUserState userState = mA11yms.getCurrentUserState();
- userState.mAccessibilityButtonTargets.clear();
- userState.mAccessibilityButtonTargets.add(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString());
+ userState.updateShortcutTargetsLocked(
+ Set.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()), SOFTWARE);
ComponentName tile = new ComponentName(
TARGET_ALWAYS_ON_A11Y_SERVICE.getPackageName(),
TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
index 9fad14d..ca30551 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
@@ -28,7 +28,10 @@
import static android.view.accessibility.AccessibilityManager.STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED;
import static android.view.accessibility.AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain;
import static com.google.common.truth.Truth.assertThat;
@@ -159,8 +162,9 @@
mUserState.setInteractiveUiTimeoutLocked(30);
mUserState.mEnabledServices.add(COMPONENT_NAME);
mUserState.mTouchExplorationGrantedServices.add(COMPONENT_NAME);
- mUserState.mAccessibilityShortcutKeyTargets.add(COMPONENT_NAME.flattenToString());
- mUserState.mAccessibilityButtonTargets.add(COMPONENT_NAME.flattenToString());
+ mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), HARDWARE);
+ mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), SOFTWARE);
+ mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), GESTURE);
mUserState.setTargetAssignedToAccessibilityButton(COMPONENT_NAME.flattenToString());
mUserState.setTouchExplorationEnabledLocked(true);
mUserState.setMagnificationSingleFingerTripleTapEnabledLocked(true);
@@ -182,8 +186,9 @@
assertEquals(0, mUserState.getInteractiveUiTimeoutLocked());
assertTrue(mUserState.mEnabledServices.isEmpty());
assertTrue(mUserState.mTouchExplorationGrantedServices.isEmpty());
- assertTrue(mUserState.mAccessibilityShortcutKeyTargets.isEmpty());
- assertTrue(mUserState.mAccessibilityButtonTargets.isEmpty());
+ assertTrue(mUserState.getShortcutTargetsLocked(HARDWARE).isEmpty());
+ assertTrue(mUserState.getShortcutTargetsLocked(SOFTWARE).isEmpty());
+ assertTrue(mUserState.getShortcutTargetsLocked(GESTURE).isEmpty());
assertNull(mUserState.getTargetAssignedToAccessibilityButton());
assertFalse(mUserState.isTouchExplorationEnabledLocked());
assertFalse(mUserState.isMagnificationSingleFingerTripleTapEnabledLocked());
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java
index 0f3b0aa..636cbee 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java
@@ -37,6 +37,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.media.permission.INativePermissionController;
+import com.android.media.permission.PermissionEnum;
import com.android.media.permission.UidPackageState;
import com.android.server.pm.pkg.PackageState;
@@ -353,6 +354,56 @@
}
@Test
+ public void testSpecialHotwordPermissions() throws Exception {
+ BiPredicate<Integer, String> customPermPred = mock(BiPredicate.class);
+ var initPackageListData =
+ List.of(mMockPackageStateOne_10000_one, mMockPackageStateTwo_10001_two);
+ // expected state
+ // PERM[CAPTURE_AUDIO_HOTWORD]: [10000]
+ // PERM[CAPTURE_AUDIO_OUTPUT]: [10001]
+ // PERM[RECORD_AUDIO]: [10001]
+ // PERM[...]: []
+ when(customPermPred.test(
+ eq(10000), eq(MONITORED_PERMS[PermissionEnum.CAPTURE_AUDIO_HOTWORD])))
+ .thenReturn(true);
+ when(customPermPred.test(
+ eq(10001), eq(MONITORED_PERMS[PermissionEnum.CAPTURE_AUDIO_OUTPUT])))
+ .thenReturn(true);
+ when(customPermPred.test(eq(10001), eq(MONITORED_PERMS[PermissionEnum.RECORD_AUDIO])))
+ .thenReturn(true);
+ mPermissionProvider =
+ new AudioServerPermissionProvider(
+ initPackageListData, customPermPred, () -> new int[] {0});
+ int HDS_UID = 99001;
+ mPermissionProvider.onServiceStart(mMockPc);
+ clearInvocations(mMockPc);
+ mPermissionProvider.setIsolatedServiceUid(HDS_UID, 10000);
+ verify(mMockPc)
+ .populatePermissionState(
+ eq((byte) PermissionEnum.CAPTURE_AUDIO_HOTWORD),
+ aryEq(new int[] {10000, HDS_UID}));
+ verify(mMockPc)
+ .populatePermissionState(
+ eq((byte) PermissionEnum.CAPTURE_AUDIO_OUTPUT),
+ aryEq(new int[] {10001, HDS_UID}));
+ verify(mMockPc)
+ .populatePermissionState(
+ eq((byte) PermissionEnum.RECORD_AUDIO), aryEq(new int[] {10001, HDS_UID}));
+
+ clearInvocations(mMockPc);
+ mPermissionProvider.clearIsolatedServiceUid(HDS_UID);
+ verify(mMockPc)
+ .populatePermissionState(
+ eq((byte) PermissionEnum.CAPTURE_AUDIO_HOTWORD), aryEq(new int[] {10000}));
+ verify(mMockPc)
+ .populatePermissionState(
+ eq((byte) PermissionEnum.CAPTURE_AUDIO_OUTPUT), aryEq(new int[] {10001}));
+ verify(mMockPc)
+ .populatePermissionState(
+ eq((byte) PermissionEnum.RECORD_AUDIO), aryEq(new int[] {10001}));
+ }
+
+ @Test
public void testPermissionsPopulated_onChange() throws Exception {
var initPackageListData =
List.of(mMockPackageStateOne_10000_one, mMockPackageStateTwo_10001_two);
diff --git a/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java b/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java
index 6d56c41..60c3659 100644
--- a/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java
+++ b/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java
@@ -17,17 +17,25 @@
import static com.google.common.truth.Truth.assertThat;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import java.util.ArrayList;
-import java.util.List;
-
@RunWith(JUnit4.class)
public class RequestIdTest {
+ private static final int TEST_DATASET_SIZE = 300;
+ private static final int TEST_WRAP_SIZE = 50; // Number of request ids before wrap happens
+ private static final String TAG = "RequestIdTest";
+
List<Integer> datasetPrimaryNoWrap = new ArrayList<>();
List<Integer> datasetPrimaryWrap = new ArrayList<>();
List<Integer> datasetSecondaryNoWrap = new ArrayList<>();
@@ -35,151 +43,200 @@
List<Integer> datasetMixedNoWrap = new ArrayList<>();
List<Integer> datasetMixedWrap = new ArrayList<>();
- @Before
- public void setup() throws Exception {
- int datasetSize = 300;
+ List<Integer> manualWrapRequestIdList = Arrays.asList(3, 9, 15,
+ RequestId.MAX_SECONDARY_REQUEST_ID - 5,
+ RequestId.MAX_SECONDARY_REQUEST_ID - 3);
+ List<Integer> manualNoWrapRequestIdList =Arrays.asList(2, 6, 10, 14, 18, 22, 26, 30);
+ List<Integer> manualOneElementRequestIdList = Arrays.asList(1);
+
+ @Before
+ public void setup() throws IllegalArgumentException {
+ Slog.d(TAG, "setup()");
{ // Generate primary only ids that do not wrap
- RequestId requestId = new RequestId(0);
- for (int i = 0; i < datasetSize; i++) {
+ RequestId requestId = new RequestId(RequestId.MIN_PRIMARY_REQUEST_ID);
+ for (int i = 0; i < TEST_DATASET_SIZE; i++) {
datasetPrimaryNoWrap.add(requestId.nextId(false));
}
+ Collections.sort(datasetPrimaryNoWrap);
}
{ // Generate primary only ids that wrap
- RequestId requestId = new RequestId(0xff00);
- for (int i = 0; i < datasetSize; i++) {
+ RequestId requestId = new RequestId(RequestId.MAX_PRIMARY_REQUEST_ID -
+ TEST_WRAP_SIZE * 2);
+ for (int i = 0; i < TEST_DATASET_SIZE; i++) {
datasetPrimaryWrap.add(requestId.nextId(false));
}
+ Collections.sort(datasetPrimaryWrap);
}
{ // Generate SECONDARY only ids that do not wrap
- RequestId requestId = new RequestId(0);
- for (int i = 0; i < datasetSize; i++) {
+ RequestId requestId = new RequestId(RequestId.MIN_SECONDARY_REQUEST_ID);
+ for (int i = 0; i < TEST_DATASET_SIZE; i++) {
datasetSecondaryNoWrap.add(requestId.nextId(true));
}
+ Collections.sort(datasetSecondaryNoWrap);
}
{ // Generate SECONDARY only ids that wrap
- RequestId requestId = new RequestId(0xff00);
- for (int i = 0; i < datasetSize; i++) {
+ RequestId requestId = new RequestId(RequestId.MAX_SECONDARY_REQUEST_ID -
+ TEST_WRAP_SIZE * 2);
+ for (int i = 0; i < TEST_DATASET_SIZE; i++) {
datasetSecondaryWrap.add(requestId.nextId(true));
}
+ Collections.sort(datasetSecondaryWrap);
}
{ // Generate MIXED only ids that do not wrap
- RequestId requestId = new RequestId(0);
- for (int i = 0; i < datasetSize; i++) {
+ RequestId requestId = new RequestId(RequestId.MIN_REQUEST_ID);
+ for (int i = 0; i < TEST_DATASET_SIZE; i++) {
datasetMixedNoWrap.add(requestId.nextId(i % 2 != 0));
}
+ Collections.sort(datasetMixedNoWrap);
}
{ // Generate MIXED only ids that wrap
- RequestId requestId = new RequestId(0xff00);
- for (int i = 0; i < datasetSize; i++) {
+ RequestId requestId = new RequestId(RequestId.MAX_REQUEST_ID -
+ TEST_WRAP_SIZE);
+ for (int i = 0; i < TEST_DATASET_SIZE; i++) {
datasetMixedWrap.add(requestId.nextId(i % 2 != 0));
}
+ Collections.sort(datasetMixedWrap);
}
+ Slog.d(TAG, "finishing setup()");
}
@Test
public void testRequestIdLists() {
+ Slog.d(TAG, "testRequestIdLists()");
for (int id : datasetPrimaryNoWrap) {
assertThat(RequestId.isSecondaryProvider(id)).isFalse();
- assertThat(id >= 0).isTrue();
- assertThat(id < 0xffff).isTrue();
+ assertThat(id).isAtLeast(RequestId.MIN_PRIMARY_REQUEST_ID);
+ assertThat(id).isAtMost(RequestId.MAX_PRIMARY_REQUEST_ID);
}
for (int id : datasetPrimaryWrap) {
assertThat(RequestId.isSecondaryProvider(id)).isFalse();
- assertThat(id >= 0).isTrue();
- assertThat(id < 0xffff).isTrue();
+ assertThat(id).isAtLeast(RequestId.MIN_PRIMARY_REQUEST_ID);
+ assertThat(id).isAtMost(RequestId.MAX_PRIMARY_REQUEST_ID);
}
for (int id : datasetSecondaryNoWrap) {
assertThat(RequestId.isSecondaryProvider(id)).isTrue();
- assertThat(id >= 0).isTrue();
- assertThat(id < 0xffff).isTrue();
+ assertThat(id).isAtLeast(RequestId.MIN_SECONDARY_REQUEST_ID);
+ assertThat(id).isAtMost(RequestId.MAX_SECONDARY_REQUEST_ID);
}
for (int id : datasetSecondaryWrap) {
assertThat(RequestId.isSecondaryProvider(id)).isTrue();
- assertThat(id >= 0).isTrue();
- assertThat(id < 0xffff).isTrue();
+ assertThat(id).isAtLeast(RequestId.MIN_SECONDARY_REQUEST_ID);
+ assertThat(id).isAtMost(RequestId.MAX_SECONDARY_REQUEST_ID);
}
}
@Test
- public void testRequestIdGeneration() {
- RequestId requestId = new RequestId(0);
+ public void testCreateNewRequestId() {
+ Slog.d(TAG, "testCreateNewRequestId()");
+ for (int i = 0; i < 100000; i++) {
+ RequestId requestId = new RequestId();
+ assertThat(requestId.getRequestId()).isAtLeast(RequestId.MIN_REQUEST_ID);
+ assertThat(requestId.getRequestId()).isAtMost(RequestId.MAX_START_ID);
+ }
+ }
+ @Test
+ public void testGetNextRequestId() throws IllegalArgumentException{
+ Slog.d(TAG, "testGetNextRequestId()");
+ RequestId requestId = new RequestId();
// Large Primary
for (int i = 0; i < 100000; i++) {
int y = requestId.nextId(false);
assertThat(RequestId.isSecondaryProvider(y)).isFalse();
- assertThat(y >= 0).isTrue();
- assertThat(y < 0xffff).isTrue();
+ assertThat(y).isAtLeast(RequestId.MIN_PRIMARY_REQUEST_ID);
+ assertThat(y).isAtMost(RequestId.MAX_PRIMARY_REQUEST_ID);
}
// Large Secondary
- requestId = new RequestId(0);
+ requestId = new RequestId();
for (int i = 0; i < 100000; i++) {
int y = requestId.nextId(true);
assertThat(RequestId.isSecondaryProvider(y)).isTrue();
- assertThat(y >= 0).isTrue();
- assertThat(y < 0xffff).isTrue();
+ assertThat(y).isAtLeast(RequestId.MIN_SECONDARY_REQUEST_ID);
+ assertThat(y).isAtMost(RequestId.MAX_SECONDARY_REQUEST_ID);
}
// Large Mixed
- requestId = new RequestId(0);
+ requestId = new RequestId();
for (int i = 0; i < 50000; i++) {
int y = requestId.nextId(i % 2 != 0);
- assertThat(RequestId.isSecondaryProvider(y)).isEqualTo(i % 2 == 0);
- assertThat(y >= 0).isTrue();
- assertThat(y < 0xffff).isTrue();
+ assertThat(y).isAtLeast(RequestId.MIN_REQUEST_ID);
+ assertThat(y).isAtMost(RequestId.MAX_REQUEST_ID);
}
}
@Test
public void testGetLastRequestId() {
- // In this test, request ids are generated FIFO, so the last entry is also the last
- // request
+ Slog.d(TAG, "testGetLastRequestId()");
- { // Primary no wrap
- int lastIdIndex = datasetPrimaryNoWrap.size() - 1;
- int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryNoWrap);
- assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
- }
-
- { // Primary wrap
- int lastIdIndex = datasetPrimaryWrap.size() - 1;
- int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryWrap);
+ { // Primary no wrap
+ int lastIdIndex = datasetPrimaryNoWrap.size() - 1;
+ int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryNoWrap);
assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
}
- { // Secondary no wrap
+ { // Primary wrap
+ // The last index would be the # of request ids left after wrap
+ // minus 1 (index starts at 0)
+ int lastIdIndex = TEST_DATASET_SIZE - TEST_WRAP_SIZE - 1;
+ int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryWrap);
+ assertThat(lastComputedIdIndex).isEqualTo(lastIdIndex);
+ }
+
+ { // Secondary no wrap
int lastIdIndex = datasetSecondaryNoWrap.size() - 1;
int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetSecondaryNoWrap);
assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
}
- { // Secondary wrap
- int lastIdIndex = datasetSecondaryWrap.size() - 1;
+ { // Secondary wrap
+ int lastIdIndex = TEST_DATASET_SIZE - TEST_WRAP_SIZE - 1;
int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetSecondaryWrap);
assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
}
- { // Mixed no wrap
+ { // Mixed no wrap
int lastIdIndex = datasetMixedNoWrap.size() - 1;
int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetMixedNoWrap);
assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
}
- { // Mixed wrap
- int lastIdIndex = datasetMixedWrap.size() - 1;
+ { // Mixed wrap
+ int lastIdIndex = TEST_DATASET_SIZE - TEST_WRAP_SIZE - 1;
int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetMixedWrap);
assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
}
+ { // Manual wrap
+ int lastIdIndex = 2; // [3, 9, 15,
+ // MAX_SECONDARY_REQUEST_ID - 5, MAX_SECONDARY_REQUEST_ID - 3]
+ int lastComputedIdIndex = RequestId.getLastRequestIdIndex(manualWrapRequestIdList);
+ assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
+ }
+
+ { // Manual no wrap
+ int lastIdIndex = manualNoWrapRequestIdList.size() - 1; // [2, 6, 10, 14,
+ // 18, 22, 26, 30]
+ int lastComputedIdIndex = RequestId.getLastRequestIdIndex(manualNoWrapRequestIdList);
+ assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
+
+ }
+
+ { // Manual one element
+ int lastIdIndex = 0; // [1]
+ int lastComputedIdIndex = RequestId.getLastRequestIdIndex(
+ manualOneElementRequestIdList);
+ assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
+
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
index 0678140..e078238 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
@@ -92,8 +92,6 @@
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Mock
- private GenericWindowPolicyController.PipBlockedCallback mPipBlockedCallback;
- @Mock
private VirtualDeviceManager.ActivityListener mActivityListener;
@Mock
private GenericWindowPolicyController.IntentListenerCallback mIntentListenerCallback;
@@ -140,7 +138,6 @@
gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
assertThat(gwpc.isEnteringPipAllowed(TEST_UID)).isFalse();
- verify(mPipBlockedCallback, timeout(TIMEOUT_MILLIS)).onEnteringPipBlocked(TEST_UID);
}
@Test
@@ -151,7 +148,6 @@
Arrays.asList(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
WindowConfiguration.WINDOWING_MODE_PINNED)));
assertThat(gwpc.isEnteringPipAllowed(TEST_UID)).isTrue();
- verify(mPipBlockedCallback, after(TIMEOUT_MILLIS).never()).onEnteringPipBlocked(TEST_UID);
}
@Test
@@ -746,7 +742,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ mSecureWindowCallback,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -767,7 +762,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ mSecureWindowCallback,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -789,7 +783,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -811,7 +804,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -833,7 +825,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -855,7 +846,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -877,7 +867,6 @@
/* crossTaskNavigationExemptions= */ Collections.singleton(blockedComponent),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -899,7 +888,6 @@
/* crossTaskNavigationExemptions= */ Collections.singleton(allowedComponent),
/* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ mIntentListenerCallback,
@@ -922,7 +910,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent= */ permissionComponent,
/* activityListener= */ mActivityListener,
- /* pipBlockedCallback= */ mPipBlockedCallback,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ mIntentListenerCallback,
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index 52f28b9..b946a43 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -87,7 +87,6 @@
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
/* permissionDialogComponent */ null,
/* activityListener= */ null,
- /* pipBlockedCallback= */ null,
/* activityBlockedCallback= */ null,
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ null,
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 2a4b797..21364b8 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -2012,38 +2012,94 @@
}
@Test
- public void handleStandby_fromActiveSource_standby() {
- mPowerManager.setInteractive(true);
- mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ public void handleStandby_fromActiveSource_previousActiveSourceSet_standby() {
+ mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
+ HdmiCecMessage activeSourceFromPlayback =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x1000);
+ HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
+ ADDR_TV);
mTestLooper.dispatchAll();
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isFalse();
+ mPowerManager.setInteractive(true);
+ mTestLooper.dispatchAll();
+
+ mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback);
mHdmiControlService.setActiveSource(ADDR_PLAYBACK_1, 0x1000,
"HdmiCecLocalDeviceTvTest");
mTestLooper.dispatchAll();
- HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
- ADDR_TV);
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isTrue();
assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
.isEqualTo(Constants.HANDLED);
mTestLooper.dispatchAll();
assertThat(mPowerManager.isInteractive()).isFalse();
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isFalse();
}
@Test
- public void handleStandby_fromNonActiveSource_noStandby() {
+ public void handleStandby_fromNonActiveSource_previousActiveSourceSet_noStandby() {
+ HdmiCecMessage activeSourceFromPlayback =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_2, 0x2000);
+ HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
+ ADDR_TV);
+ mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isFalse();
mPowerManager.setInteractive(true);
- mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+
+ mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback);
mHdmiControlService.setActiveSource(ADDR_PLAYBACK_2, 0x2000,
"HdmiCecLocalDeviceTvTest");
mTestLooper.dispatchAll();
- HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
- ADDR_TV);
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isTrue();
assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
.isEqualTo(Constants.HANDLED);
mTestLooper.dispatchAll();
assertThat(mPowerManager.isInteractive()).isTrue();
}
+
+
+ @Test
+ public void handleStandby_fromNonActiveSource_previousActiveSourceNotSet_Standby() {
+ HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
+ ADDR_TV);
+ mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isFalse();
+ mPowerManager.setInteractive(true);
+
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isFalse();
+ assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
+ .isEqualTo(Constants.HANDLED);
+ mTestLooper.dispatchAll();
+
+ assertThat(mPowerManager.isInteractive()).isFalse();
+ assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+ .isFalse();
+ }
+
+ protected static class MockTvDevice extends HdmiCecLocalDeviceTv {
+ MockTvDevice(HdmiControlService service) {
+ super(service);
+ }
+
+ @Override
+ protected int handleActiveSource(HdmiCecMessage message) {
+ setWasActiveSourceSetToConnectedDevice(true);
+ return super.handleActiveSource(message);
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java
index 70150c5..4396c67 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenRepairModeTest.java
@@ -19,6 +19,8 @@
import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE;
import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
@@ -199,6 +201,27 @@
.getResponseCode());
}
+ @Test
+ public void writeRepairModeCredential_noLock() {
+ assertThat(mService.writeRepairModeCredential(PRIMARY_USER_ID)).isFalse();
+ }
+
+ @Test
+ public void writeRepairModeCredential_hasLock() {
+ mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+ assertThat(mService.writeRepairModeCredential(PRIMARY_USER_ID)).isTrue();
+ }
+
+ @Test
+ public void writeRepairModeCredential_verifyRepairModeUser() {
+ mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+ mService.writeRepairModeCredential(PRIMARY_USER_ID);
+ setRepairModeActive(true);
+
+ var response = mService.verifyCredential(newPin("1234"), USER_REPAIR_MODE, 0);
+ assertThat(response.isMatched()).isTrue();
+ }
+
private void setRepairModeActive(boolean active) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.REPAIR_MODE_ACTIVE, active ? 1 : 0);
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 37065fd..02d3b59 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -1424,6 +1424,39 @@
@MediumTest
@Test
+ public void testSerialNumberAfterUserRemoval() {
+ final UserInfo user = mUserManager.createUser("Test User", 0);
+ assertThat(user).isNotNull();
+
+ final int userId = user.id;
+ assertThat(mUserManager.getUserSerialNumber(userId))
+ .isEqualTo(user.serialNumber);
+ mUsersToRemove.add(userId);
+ removeUser(userId);
+ int serialNumber = mUserManager.getUserSerialNumber(userId);
+ int timeout = REMOVE_USER_TIMEOUT_SECONDS * 5; // called every 200ms
+
+ // Wait for the user to be removed from memory
+ while(serialNumber > 0 && timeout > 0){
+ sleep(200);
+ timeout--;
+ serialNumber = mUserManager.getUserSerialNumber(userId);
+ }
+ assertThat(serialNumber).isEqualTo(-1);
+ }
+
+
+ private void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ @MediumTest
+ @Test
public void testMaxUsers() {
int N = UserManager.getMaxSupportedUsers();
int count = mUserManager.getUsers().size();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index ff4bc21..d151345 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -120,6 +120,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionManager;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -2127,6 +2128,7 @@
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
@@ -2907,6 +2909,7 @@
}
@Test
+ @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
public void testOnlyHasDefaultChannel() throws Exception {
assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
@@ -3317,9 +3320,7 @@
assertEquals(3, actual.size());
for (NotificationChannelGroup group : actual) {
if (group.getId() == null) {
- assertEquals(
- notificationClassification() ? 6 : 2,
- group.getChannels().size()); // misc channel too
+ assertEquals(2, group.getChannels().size());
assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
|| channel3.getId().equals(group.getChannels().get(1).getId()));
} else if (group.getId().equals(ncg.getId())) {
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index b292294..6ba2c70 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -28,7 +28,7 @@
],
tools: ["protologtool"],
cmd: "$(location protologtool) transform-protolog-calls " +
- "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+ "--protolog-class com.android.internal.protolog.ProtoLog " +
"--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
"--loggroups-jar $(location :protolog-groups) " +
// Used for the ProtoLogIntegrationTest, where don't test decoding or writing to file
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
index 2e571bb..aa28147 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -132,8 +132,9 @@
KeyboardLogEvent.VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_DOWN, 0},
{"VOLUME_MUTE key -> Mute Volume", new int[]{KeyEvent.KEYCODE_VOLUME_MUTE},
KeyboardLogEvent.VOLUME_MUTE, KeyEvent.KEYCODE_VOLUME_MUTE, 0},
- {"ALL_APPS key -> Open App Drawer", new int[]{KeyEvent.KEYCODE_ALL_APPS},
- KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_ALL_APPS, 0},
+ {"ALL_APPS key -> Open App Drawer in Accessibility mode",
+ new int[]{KeyEvent.KEYCODE_ALL_APPS},
+ KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, KeyEvent.KEYCODE_ALL_APPS, 0},
{"SEARCH key -> Launch Search Activity", new int[]{KeyEvent.KEYCODE_SEARCH},
KeyboardLogEvent.LAUNCH_SEARCH, KeyEvent.KEYCODE_SEARCH, 0},
{"LANGUAGE_SWITCH key -> Switch Keyboard Language",
@@ -259,14 +260,15 @@
{"Long press META + H -> Launch assistant",
new int[]{META_KEY, KeyEvent.KEYCODE_H}, LONG_PRESS_HOME_ASSIST,
KeyboardLogEvent.LAUNCH_ASSISTANT, KeyEvent.KEYCODE_H, META_ON},
- {"Long press HOME key -> Open App Drawer",
+ {"Long press HOME key -> Open App Drawer in Accessibility mode",
new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_ALL_APPS,
- KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_HOME, 0},
- {"Long press META + ENTER -> Open App Drawer",
+ KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, KeyEvent.KEYCODE_HOME, 0},
+ {"Long press META + ENTER -> Open App Drawer in Accessibility mode",
new int[]{META_KEY, KeyEvent.KEYCODE_ENTER}, LONG_PRESS_HOME_ALL_APPS,
- KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_ENTER, META_ON},
- {"Long press META + H -> Open App Drawer", new int[]{META_KEY, KeyEvent.KEYCODE_H},
- LONG_PRESS_HOME_ALL_APPS, KeyboardLogEvent.ALL_APPS,
+ KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, KeyEvent.KEYCODE_ENTER, META_ON},
+ {"Long press META + H -> Open App Drawer in Accessibility mode",
+ new int[]{META_KEY, KeyEvent.KEYCODE_H},
+ LONG_PRESS_HOME_ALL_APPS, KeyboardLogEvent.ACCESSIBILITY_ALL_APPS,
KeyEvent.KEYCODE_H, META_ON}};
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java
index 12ab3e1..a3252f8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java
@@ -103,8 +103,8 @@
@Test
public void testShouldRefreshActivity_refreshDisabledForActivity() throws Exception {
configureActivityAndDisplay();
- when(mActivity.mLetterboxUiController.shouldRefreshActivityForCameraCompat())
- .thenReturn(false);
+ when(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldRefreshActivityForCameraCompat()).thenReturn(false);
mActivityRefresher.addEvaluator(mEvaluatorTrue);
mActivityRefresher.onActivityConfigurationChanging(mActivity, mNewConfig, mOldConfig);
@@ -160,8 +160,9 @@
throws Exception {
configureActivityAndDisplay();
mActivityRefresher.addEvaluator(mEvaluatorTrue);
- doReturn(true).when(mActivity.mLetterboxUiController)
- .shouldRefreshActivityViaPauseForCameraCompat();
+ doReturn(true)
+ .when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+ .shouldRefreshActivityViaPauseForCameraCompat();
mActivityRefresher.onActivityConfigurationChanging(mActivity, mNewConfig, mOldConfig);
@@ -172,8 +173,9 @@
public void testOnActivityRefreshed_setIsRefreshRequestedToFalse() throws Exception {
configureActivityAndDisplay();
mActivityRefresher.addEvaluator(mEvaluatorTrue);
- doReturn(true).when(mActivity.mLetterboxUiController)
- .shouldRefreshActivityViaPauseForCameraCompat();
+ doReturn(true)
+ .when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+ .shouldRefreshActivityViaPauseForCameraCompat();
mActivityRefresher.onActivityRefreshed(mActivity);
@@ -186,8 +188,8 @@
private void assertActivityRefreshRequested(boolean refreshRequested,
boolean cycleThroughStop) throws Exception {
- verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0))
- .setIsRefreshRequested(true);
+ verify(mActivity.mAppCompatController.getAppCompatCameraOverrides(),
+ times(refreshRequested ? 1 : 0)).setIsRefreshRequested(true);
final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain(mActivity.token,
cycleThroughStop ? ON_STOP : ON_PAUSE);
@@ -211,9 +213,9 @@
.getTopMostActivity();
spyOn(mActivity.mLetterboxUiController);
- doReturn(true).when(
- mActivity.mLetterboxUiController).shouldRefreshActivityForCameraCompat();
-
+ spyOn(mActivity.mAppCompatController.getAppCompatCameraOverrides());
doReturn(true).when(mActivity).inFreeformWindowingMode();
+ doReturn(true).when(mActivity.mAppCompatController
+ .getAppCompatCameraOverrides()).shouldRefreshActivityForCameraCompat();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
new file mode 100644
index 0000000..467050e
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2024 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.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.app.WindowConfiguration;
+import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.wm.utils.TestComponentStack;
+
+import org.junit.Assert;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * Robot implementation for {@link ActivityRecord}.
+ */
+class AppCompatActivityRobot {
+
+ private static final int DEFAULT_DISPLAY_WIDTH = 1000;
+ private static final int DEFAULT_DISPLAY_HEIGHT = 2000;
+
+ private static final float DELTA_ASPECT_RATIO_TOLERANCE = 0.0001f;
+ private static final float COMPAT_SCALE_TOLERANCE = 0.0001f;
+
+ private static final String TEST_COMPONENT_NAME = AppCompatActivityRobot.class.getName();
+
+ @NonNull
+ private final ActivityTaskManagerService mAtm;
+ @NonNull
+ private final ActivityTaskSupervisor mSupervisor;
+ @NonNull
+ private final TestComponentStack<ActivityRecord> mActivityStack;
+ @NonNull
+ private final TestComponentStack<Task> mTaskStack;
+
+ private final int mDisplayWidth;
+ private final int mDisplayHeight;
+
+ AppCompatActivityRobot(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor,
+ int displayWidth, int displayHeight) {
+ mAtm = atm;
+ mSupervisor = supervisor;
+ mDisplayWidth = displayWidth;
+ mDisplayHeight = displayHeight;
+ mActivityStack = new TestComponentStack<>();
+ mTaskStack = new TestComponentStack<>();
+ }
+
+ AppCompatActivityRobot(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor) {
+ this(wm, atm, supervisor, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
+ }
+
+ void createActivityWithComponent() {
+ createActivityWithComponentInNewTask(/* inNewTask */ mTaskStack.isEmpty());
+ }
+
+ void createActivityWithComponentInNewTask() {
+ createActivityWithComponentInNewTask(/* inNewTask */ true);
+ }
+
+ void configureTopActivity(float minAspect, float maxAspect, int screenOrientation,
+ boolean isUnresizable) {
+ prepareLimitedBounds(mActivityStack.top(), minAspect, maxAspect, screenOrientation,
+ isUnresizable);
+ }
+
+ void configureTopActivityIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
+ mActivityStack.top().mDisplayContent
+ .setIgnoreOrientationRequest(ignoreOrientationRequest);
+ }
+
+ void configureUnresizableTopActivity(@ActivityInfo.ScreenOrientation int screenOrientation) {
+ configureTopActivity(/* minAspect */ -1, /* maxAspect */ -1, screenOrientation,
+ /* isUnresizable */ true);
+ }
+
+ @NonNull
+ ActivityRecord top() {
+ return mActivityStack.top();
+ }
+
+ @NonNull
+ ActivityRecord getFromTop(int fromTop) {
+ return mActivityStack.getFromTop(fromTop);
+ }
+
+ void setTaskWindowingMode(@WindowConfiguration.WindowingMode int windowingMode) {
+ mTaskStack.top().setWindowingMode(windowingMode);
+ }
+
+ void setLetterboxedForFixedOrientationAndAspectRatio(boolean enabled) {
+ doReturn(enabled).when(mActivityStack.top())
+ .isLetterboxedForFixedOrientationAndAspectRatio();
+ }
+
+ void enableTreatmentForTopActivity(boolean enabled) {
+ doReturn(enabled).when(getTopDisplayRotationCompatPolicy())
+ .isTreatmentEnabledForActivity(eq(mActivityStack.top()));
+ }
+
+ void setTopActivityCameraActive(boolean enabled) {
+ doReturn(enabled).when(getTopDisplayRotationCompatPolicy())
+ .isCameraActive(eq(mActivityStack.top()), /* mustBeFullscreen= */ eq(true));
+ }
+
+ void setTopActivityEligibleForOrientationOverride(boolean enabled) {
+ doReturn(enabled).when(getTopDisplayRotationCompatPolicy())
+ .isActivityEligibleForOrientationOverride(eq(mActivityStack.top()));
+ }
+
+ void setShouldApplyUserMinAspectRatioOverride(boolean enabled) {
+ doReturn(enabled).when(mActivityStack.top()
+ .mLetterboxUiController).shouldApplyUserMinAspectRatioOverride();
+ }
+
+ void setShouldCreateCompatDisplayInsets(boolean enabled) {
+ doReturn(enabled).when(mActivityStack.top()).shouldCreateCompatDisplayInsets();
+ }
+
+ void setShouldApplyUserFullscreenOverride(boolean enabled) {
+ doReturn(enabled).when(mActivityStack.top()
+ .mLetterboxUiController).shouldApplyUserFullscreenOverride();
+ }
+
+ void setGetUserMinAspectRatioOverrideCode(@PackageManager.UserMinAspectRatio int orientation) {
+ doReturn(orientation).when(mActivityStack.top()
+ .mLetterboxUiController).getUserMinAspectRatioOverrideCode();
+ }
+
+ void setIgnoreOrientationRequest(boolean enabled) {
+ mActivityStack.top().mDisplayContent.setIgnoreOrientationRequest(enabled);
+ }
+
+ void setTopActivityAsEmbedded(boolean embedded) {
+ doReturn(embedded).when(mActivityStack.top()).isEmbedded();
+ }
+
+ void destroyTopActivity() {
+ mActivityStack.top().removeImmediately();
+ }
+
+ void destroyActivity(int fromTop) {
+ mActivityStack.applyTo(/* fromTop */ fromTop, ActivityRecord::removeImmediately);
+ }
+
+ void createNewTask() {
+ final DisplayContent displayContent = new TestDisplayContent
+ .Builder(mAtm, mDisplayWidth, mDisplayHeight).build();
+ final Task newTask = new WindowTestsBase.TaskBuilder(mSupervisor)
+ .setDisplay(displayContent).build();
+ mTaskStack.push(newTask);
+ }
+
+ void createNewTaskWithBaseActivity() {
+ final DisplayContent displayContent = new TestDisplayContent
+ .Builder(mAtm, mDisplayWidth, mDisplayHeight).build();
+ final Task newTask = new WindowTestsBase.TaskBuilder(mSupervisor)
+ .setCreateActivity(true)
+ .setDisplay(displayContent).build();
+ mTaskStack.push(newTask);
+ pushActivity(newTask.getTopNonFinishingActivity());
+ }
+
+ void attachTopActivityToTask() {
+ mTaskStack.top().addChild(mActivityStack.top());
+ }
+
+ void applyToTopActivity(Consumer<ActivityRecord> consumer) {
+ consumer.accept(mActivityStack.top());
+ }
+
+ void applyToActivity(int fromTop, @NonNull Consumer<ActivityRecord> consumer) {
+ mActivityStack.applyTo(fromTop, consumer);
+ }
+
+ void applyToAllActivities(@NonNull Consumer<ActivityRecord> consumer) {
+ mActivityStack.applyToAll(consumer);
+ }
+
+ void rotateDisplayForTopActivity(@Surface.Rotation int rotation) {
+ rotateDisplay(mActivityStack.top().mDisplayContent, rotation);
+ }
+
+ void configureTopActivityFoldablePosture(boolean isHalfFolded, boolean isTabletop) {
+ mActivityStack.applyToTop((topActivity) -> {
+ final DisplayRotation r = topActivity.mDisplayContent.getDisplayRotation();
+ doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge();
+ doReturn(false).when(r)
+ .isDeviceInPosture(any(DeviceStateController.DeviceState.class),
+ anyBoolean());
+ if (isHalfFolded) {
+ doReturn(true).when(r)
+ .isDeviceInPosture(DeviceStateController.DeviceState.HALF_FOLDED,
+ isTabletop);
+ }
+ topActivity.recomputeConfiguration();
+ });
+ }
+
+ private static void rotateDisplay(@Surface.Rotation DisplayContent display, int rotation) {
+ final Configuration c = new Configuration();
+ display.getDisplayRotation().setRotation(rotation);
+ display.computeScreenConfiguration(c);
+ display.onRequestedOverrideConfigurationChanged(c);
+ }
+
+ void assertTrueOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
+ mActivityStack.applyTo(fromTop, (activity) -> {
+ Assert.assertTrue(predicate.test(activity));
+ });
+ }
+
+ void assertFalseOnTopActivity(Predicate<ActivityRecord> predicate) {
+ Assert.assertFalse(predicate.test(mActivityStack.top()));
+ }
+
+ void assertFalseOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
+ mActivityStack.applyTo(fromTop, (activity) -> {
+ Assert.assertFalse(predicate.test(activity));
+ });
+ }
+
+ void assertNotNullOnTopActivity(Function<ActivityRecord, Object> getter) {
+ Assert.assertNotNull(getter.apply(mActivityStack.top()));
+ }
+
+ void assertNullOnTopActivity(Function<ActivityRecord, Object> getter) {
+ Assert.assertNull(getter.apply(mActivityStack.top()));
+ }
+
+ void checkTopActivityRecomputedConfiguration() {
+ verify(mActivityStack.top()).recomputeConfiguration();
+ }
+
+ void checkTopActivityConfigOrientation(@Configuration.Orientation int orientation) {
+ Assert.assertEquals(orientation, mActivityStack.top()
+ .getRequestedConfigurationOrientation());
+ }
+
+ void checkTopActivityAspectRatios(float minAspectRatio, float maxAspectRatio) {
+ final ActivityRecord topActivity = mActivityStack.top();
+ Assert.assertEquals(minAspectRatio, topActivity.getMinAspectRatio(),
+ DELTA_ASPECT_RATIO_TOLERANCE);
+ Assert.assertEquals(maxAspectRatio, topActivity.getMaxAspectRatio(),
+ DELTA_ASPECT_RATIO_TOLERANCE);
+ }
+
+ void checkTopActivityInSizeCompatMode(boolean inScm) {
+ final ActivityRecord topActivity = mActivityStack.top();
+ Assert.assertEquals(inScm, topActivity.inSizeCompatMode());
+ Assert.assertNotEquals(1f, topActivity.getCompatScale(), COMPAT_SCALE_TOLERANCE);
+ }
+
+ void launchActivity(float minAspectRatio, float maxAspectRatio,
+ @ActivityInfo.ScreenOrientation int orientation, boolean transparent,
+ boolean withComponent, boolean addToTask) {
+ final WindowTestsBase.ActivityBuilder
+ activityBuilder = new WindowTestsBase.ActivityBuilder(mAtm)
+ .setScreenOrientation(orientation)
+ .setLaunchedFromUid(0);
+ if (transparent) {
+ activityBuilder.setActivityTheme(android.R.style.Theme_Translucent);
+ }
+ if (withComponent) {
+ // Set the component to be that of the test class in order
+ // to enable compat changes
+ activityBuilder.setComponent(ComponentName.createRelative(mAtm.mContext,
+ TEST_COMPONENT_NAME));
+ }
+ if (minAspectRatio >= 0) {
+ activityBuilder.setMinAspectRatio(minAspectRatio);
+ }
+ if (maxAspectRatio >= 0) {
+ activityBuilder.setMaxAspectRatio(maxAspectRatio);
+ }
+ final ActivityRecord newActivity = activityBuilder.build();
+ if (addToTask) {
+ if (mTaskStack.isEmpty()) {
+ createNewTask();
+ }
+ mTaskStack.top().addChild(newActivity);
+ }
+ pushActivity(newActivity);
+ }
+
+ private void createActivityWithComponentInNewTask(boolean inNewTask) {
+ if (inNewTask) {
+ createNewTask();
+ }
+ final ActivityRecord activity = new WindowTestsBase.ActivityBuilder(mAtm)
+ .setOnTop(true)
+ .setTask(mTaskStack.top())
+ // Set the component to be that of the test class in order
+ // to enable compat changes
+ .setComponent(ComponentName.createRelative(mAtm.mContext, TEST_COMPONENT_NAME))
+ .build();
+ pushActivity(activity);
+ }
+
+ /**
+ * Setups activity with restriction on its bounds, such as maxAspect, minAspect,
+ * fixed orientation, and/or whether it is resizable.
+ */
+ private void prepareLimitedBounds(ActivityRecord activity, float minAspect, float maxAspect,
+ @ActivityInfo.ScreenOrientation int screenOrientation, boolean isUnresizable) {
+ activity.info.resizeMode = isUnresizable
+ ? RESIZE_MODE_UNRESIZEABLE
+ : RESIZE_MODE_RESIZEABLE;
+ final Task task = activity.getTask();
+ if (task != null) {
+ // Update the Task resize value as activity will follow the task.
+ task.mResizeMode = activity.info.resizeMode;
+ task.getRootActivity().info.resizeMode = activity.info.resizeMode;
+ }
+ activity.setVisibleRequested(true);
+ if (maxAspect >= 0) {
+ activity.info.setMaxAspectRatio(maxAspect);
+ }
+ if (minAspect >= 0) {
+ activity.info.setMinAspectRatio(minAspect);
+ }
+ if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
+ activity.info.screenOrientation = screenOrientation;
+ activity.setRequestedOrientation(screenOrientation);
+ }
+ // Make sure to use the provided configuration to construct the size compat fields.
+ activity.clearSizeCompatMode();
+ activity.ensureActivityConfiguration();
+ // Make sure the display configuration reflects the change of activity.
+ if (activity.mDisplayContent.updateOrientation()) {
+ activity.mDisplayContent.sendNewConfiguration();
+ }
+ }
+
+ private DisplayRotationCompatPolicy getTopDisplayRotationCompatPolicy() {
+ return mActivityStack.top().mDisplayContent.mDisplayRotationCompatPolicy;
+ }
+
+ // We add the activity to the stack and spyOn() on its properties.
+ private void pushActivity(@NonNull ActivityRecord activity) {
+ mActivityStack.push(activity);
+ spyOn(activity);
+ spyOn(activity.mAppCompatController.getTransparentPolicy());
+ if (activity.mDisplayContent != null
+ && activity.mDisplayContent.mDisplayRotationCompatPolicy != null) {
+ spyOn(activity.mDisplayContent.mDisplayRotationCompatPolicy);
+ }
+ spyOn(activity.mLetterboxUiController);
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
new file mode 100644
index 0000000..9263b4f
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2024 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.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
+import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.testng.Assert;
+
+import java.util.function.Consumer;
+
+/**
+ * Test class for {@link AppCompatCameraOverrides}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatCameraOverridesTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatCameraOverridesTest extends WindowTestsBase {
+
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+ @Test
+ public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(false);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+ public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+ public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityForCameraCompat(false);
+ });
+ }
+
+ @Test
+ public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().disable(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityForCameraCompat(false);
+ });
+ }
+
+ @Test
+ public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityForCameraCompat(true);
+ });
+ }
+
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+ public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(false);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityViaPauseForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+ public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityViaPauseForCameraCompat(true);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+ public void testShouldRefreshActivityViaPauseForCameraCompat_propertyFalseAndOverrideFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().disable(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityViaPauseForCameraCompat(false);
+ });
+ }
+
+ @Test
+ public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().enable(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldRefreshActivityViaPauseForCameraCompat(true);
+ });
+ }
+
+ @Test
+ public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(false);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldForceRotateForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+ public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldForceRotateForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+ public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldForceRotateForCameraCompat(false);
+ });
+ }
+
+ @Test
+ public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().disable(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldForceRotateForCameraCompat(false);
+ });
+ }
+
+ @Test
+ public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatTreatment(true);
+ robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldForceRotateForCameraCompat(true);
+ });
+ }
+
+ @Test
+ @DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testShouldApplyCameraCompatFreeformTreatment_flagIsDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldApplyFreeformTreatmentForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
+ @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testShouldApplyCameraCompatFreeformTreatment_overrideEnabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldApplyFreeformTreatmentForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
+ @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testShouldApplyCameraCompatFreeformTreatment_disabledByOverride_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldApplyFreeformTreatmentForCameraCompat(false);
+ });
+ }
+
+ @Test
+ @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+ public void testShouldApplyCameraCompatFreeformTreatment_notDisabledByOverride_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponentInNewTask();
+
+ robot.checkShouldApplyFreeformTreatmentForCameraCompat(true);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA,
+ OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
+ public void testShouldRecomputeConfigurationForCameraCompat() {
+ runTestScenario((robot) -> {
+ robot.conf().enableCameraCompatSplitScreenAspectRatio(true);
+ robot.activity().createActivityWithComponentInNewTask();
+ robot.activateCamera(true);
+ robot.activity().setShouldCreateCompatDisplayInsets(false);
+
+ robot.checkShouldApplyFreeformTreatmentForCameraCompat(true);
+ });
+ }
+
+ /**
+ * Runs a test scenario providing a Robot.
+ */
+ void runTestScenario(@NonNull Consumer<CameraOverridesRobotTest> consumer) {
+ spyOn(mWm.mLetterboxConfiguration);
+ final CameraOverridesRobotTest robot = new CameraOverridesRobotTest(mWm, mAtm, mSupervisor);
+ consumer.accept(robot);
+ }
+
+ private static class CameraOverridesRobotTest extends AppCompatRobotBase {
+
+ CameraOverridesRobotTest(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm,
+ @NonNull ActivityTaskSupervisor supervisor) {
+ super(wm, atm, supervisor);
+ }
+
+ void activateCamera(boolean isCameraActive) {
+ doReturn(isCameraActive).when(activity().top()).isCameraActive();
+ }
+
+ void checkShouldRefreshActivityForCameraCompat(boolean expected) {
+ Assert.assertEquals(getAppCompatCameraOverrides()
+ .shouldRefreshActivityForCameraCompat(), expected);
+ }
+
+ void checkShouldRefreshActivityViaPauseForCameraCompat(boolean expected) {
+ Assert.assertEquals(getAppCompatCameraOverrides()
+ .shouldRefreshActivityViaPauseForCameraCompat(), expected);
+ }
+
+ void checkShouldForceRotateForCameraCompat(boolean expected) {
+ Assert.assertEquals(getAppCompatCameraOverrides()
+ .shouldForceRotateForCameraCompat(), expected);
+ }
+
+ void checkShouldApplyFreeformTreatmentForCameraCompat(boolean expected) {
+ Assert.assertEquals(getAppCompatCameraOverrides()
+ .shouldApplyFreeformTreatmentForCameraCompat(), expected);
+ }
+
+ private AppCompatCameraOverrides getAppCompatCameraOverrides() {
+ return activity().top().mAppCompatController.getAppCompatCameraOverrides();
+ }
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java
new file mode 100644
index 0000000..4116313
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2024 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.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
+import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+
+/**
+ * Test class for {@link AppCompatCameraPolicy}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatCameraPolicyTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatCameraPolicyTest extends WindowTestsBase {
+
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+ @Test
+ @DisableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
+ public void testRecomputeConfigurationForCameraCompatIfNeeded_allDisabledNoRecompute() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.conf().enableCameraCompatSplitScreenAspectRatio(false);
+ robot.activateCamera(/* isCameraActive */ false);
+
+ robot.recomputeConfigurationForCameraCompatIfNeeded();
+ robot.checkRecomputeConfigurationInvoked(/* invoked */ false);
+
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
+ public void testRecomputeConfigurationForCameraCompatIfNeeded_cameraEnabledRecompute() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.conf().enableCameraCompatSplitScreenAspectRatio(false);
+ robot.activateCamera(/* isCameraActive */ false);
+
+ robot.recomputeConfigurationForCameraCompatIfNeeded();
+ robot.checkRecomputeConfigurationInvoked(/* invoked */ true);
+ });
+ }
+
+ @Test
+ @DisableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
+ public void testRecomputeConfigurationForCameraSplitScreenCompatIfNeeded_recompute() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.conf().enableCameraCompatSplitScreenAspectRatio(true);
+ robot.activateCamera(/* isCameraActive */ false);
+
+ robot.recomputeConfigurationForCameraCompatIfNeeded();
+ robot.checkRecomputeConfigurationInvoked(/* invoked */ true);
+ });
+ }
+
+ @Test
+ @DisableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
+ @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
+ public void testRecomputeConfigurationForCameraSplitScreenCompatIfNeededWithCamera_recompute() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.conf().enableCameraCompatSplitScreenAspectRatio(false);
+ robot.activateCamera(/* isCameraActive */ true);
+
+ robot.recomputeConfigurationForCameraCompatIfNeeded();
+ robot.checkRecomputeConfigurationInvoked(/* invoked */ true);
+ });
+ }
+
+ void runTestScenario(@NonNull Consumer<CameraPolicyRobotTest> consumer) {
+ spyOn(mWm.mLetterboxConfiguration);
+ final CameraPolicyRobotTest robot = new CameraPolicyRobotTest(mWm, mAtm, mSupervisor);
+ consumer.accept(robot);
+ }
+
+ private static class CameraPolicyRobotTest extends AppCompatRobotBase {
+
+ private final WindowManagerService mWm;
+
+ CameraPolicyRobotTest(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm,
+ @NonNull ActivityTaskSupervisor supervisor) {
+ super(wm, atm, supervisor);
+ mWm = wm;
+ spyOn(mWm);
+ }
+
+ void activateCamera(boolean isCameraActive) {
+ doReturn(isCameraActive).when(activity().top()).isCameraActive();
+ }
+
+ void recomputeConfigurationForCameraCompatIfNeeded() {
+ getAppCompatCameraPolicy().recomputeConfigurationForCameraCompatIfNeeded();
+ }
+
+ void checkRecomputeConfigurationInvoked(boolean invoked) {
+ if (invoked) {
+ verify(activity().top()).recomputeConfiguration();
+ } else {
+ verify(activity().top(), never()).recomputeConfiguration();
+ }
+ }
+
+ private AppCompatCameraPolicy getAppCompatCameraPolicy() {
+ return activity().top().mAppCompatController.getAppCompatCameraPolicy();
+ }
+ }
+
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatComponentPropRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatComponentPropRobot.java
new file mode 100644
index 0000000..d568eec
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatComponentPropRobot.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 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.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+
+import android.content.pm.PackageManager;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Robot class for optIn/optOut properties.
+ */
+class AppCompatComponentPropRobot {
+ @NonNull
+ private final WindowManagerService mWm;
+
+ AppCompatComponentPropRobot(@NonNull WindowManagerService wm) {
+ mWm = wm;
+ }
+
+ void enable(@NonNull String propertyName) {
+ setPropertyValue(propertyName, /* enabled */ true);
+ }
+
+ void disable(@NonNull String propertyName) {
+ setPropertyValue(propertyName, /* enabled */ false);
+ }
+
+ private void setPropertyValue(@NonNull String propertyName, boolean enabled) {
+ final PackageManager.Property property = new PackageManager.Property(propertyName,
+ /* value */ enabled, /* packageName */ "", /* className */ "");
+ final PackageManager pm = mWm.mContext.getPackageManager();
+ spyOn(pm);
+ try {
+ doReturn(property).when(pm).getProperty(eq(propertyName), anyString());
+ } catch (PackageManager.NameNotFoundException e) {
+ fail(e.getLocalizedMessage());
+ }
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxConfigurationRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxConfigurationRobot.java
new file mode 100644
index 0000000..e1da913
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxConfigurationRobot.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2024 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.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.mockito.Mockito.when;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Robot implementation for {@link LetterboxConfiguration}.
+ */
+class AppCompatLetterboxConfigurationRobot {
+
+ @NonNull
+ private final LetterboxConfiguration mLetterboxConfiguration;
+
+ AppCompatLetterboxConfigurationRobot(@NonNull LetterboxConfiguration letterboxConfiguration) {
+ mLetterboxConfiguration = letterboxConfiguration;
+ spyOn(mLetterboxConfiguration);
+ }
+
+ void enableTranslucentPolicy(boolean enabled) {
+ when(mLetterboxConfiguration.isTranslucentLetterboxingEnabled()).thenReturn(enabled);
+ }
+
+ void enablePolicyForIgnoringRequestedOrientation(boolean enabled) {
+ doReturn(enabled).when(mLetterboxConfiguration)
+ .isPolicyForIgnoringRequestedOrientationEnabled();
+ }
+
+ void enableCameraCompatTreatment(boolean enabled) {
+ doReturn(enabled).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
+ }
+
+ void enableCameraCompatTreatmentAtBuildTime(boolean enabled) {
+ doReturn(enabled).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabledAtBuildTime();
+ }
+
+ void enableUserAppAspectRatioFullscreen(boolean enabled) {
+ doReturn(enabled).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
+ }
+
+ void enableUserAppAspectRatioSettings(boolean enabled) {
+ doReturn(enabled).when(mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
+ }
+
+ void enableCameraCompatSplitScreenAspectRatio(boolean enabled) {
+ doReturn(enabled).when(mLetterboxConfiguration)
+ .isCameraCompatSplitScreenAspectRatioEnabled();
+ }
+
+
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationCapabilityTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationCapabilityTest.java
deleted file mode 100644
index f1cf866..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationCapabilityTest.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (C) 2024 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.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
-import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.server.wm.AppCompatOrientationCapability.OrientationCapabilityState.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
-import static com.android.server.wm.AppCompatOrientationCapability.OrientationCapabilityState.SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-
-import android.compat.testing.PlatformCompatChangeRule;
-import android.content.ComponentName;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.annotation.NonNull;
-
-import com.android.server.wm.utils.TestComponentStack;
-
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-
-import java.util.function.Consumer;
-import java.util.function.IntConsumer;
-import java.util.function.LongSupplier;
-
-/**
- * Test class for {@link AppCompatOrientationCapability}.
- * <p>
- * Build/Install/Run:
- * atest WmTests:AppCompatOrientationCapabilityTest
- */
-@Presubmit
-@RunWith(WindowTestRunner.class)
-public class AppCompatOrientationCapabilityTest extends WindowTestsBase {
-
- @Rule
- public TestRule compatChangeRule = new PlatformCompatChangeRule();
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
- public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
- public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
- runTestScenario((robot) -> {
- robot.prepareIsCameraCompatTreatmentEnabled(true);
- robot.prepareIsCameraCompatTreatmentEnabledAtBuildTime(true);
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
-
- robot.createActivityWithComponentInNewTask();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(false);
- robot.prepareIsTreatmentEnabledForTopActivity(true);
-
- robot.checkShouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
-
- robot.createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldNotIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.enableProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
-
- robot.createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
- public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
- throws Exception {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.disableProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
-
- robot.createActivityWithComponent();
- robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
-
- robot.checkShouldNotIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- @Test
- public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.createActivityWithComponent();
- robot.prepareIsLetterboxedForFixedOrientationAndAspectRatio(false);
-
- robot.checkRequestLoopExtended((i) -> {
- robot.checkShouldNotIgnoreOrientationLoop();
- robot.checkExpectedLoopCount(/* expectedCount */ 0);
- });
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
- public void testShouldIgnoreOrientationRequestLoop_propertyIsFalseAndOverride_returnsFalse() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.disableProperty(
- PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED);
- robot.createActivityWithComponent();
- robot.prepareIsLetterboxedForFixedOrientationAndAspectRatio(false);
-
- robot.checkRequestLoopExtended((i) -> {
- robot.checkShouldNotIgnoreOrientationLoop();
- robot.checkExpectedLoopCount(/* expectedCount */ 0);
- });
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
- public void testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.createActivityWithComponent();
- robot.prepareIsLetterboxedForFixedOrientationAndAspectRatio(true);
-
- robot.checkRequestLoopExtended((i) -> {
- robot.checkShouldNotIgnoreOrientationLoop();
- robot.checkExpectedLoopCount(/* expectedCount */ i);
- });
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
- public void testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.createActivityWithComponent();
- robot.prepareIsLetterboxedForFixedOrientationAndAspectRatio(false);
-
- robot.checkShouldNotIgnoreOrientationLoop();
- robot.checkExpectedLoopCount(/* expectedCount */ 0);
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
- public void testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.createActivityWithComponent();
- robot.prepareIsLetterboxedForFixedOrientationAndAspectRatio(false);
-
- robot.prepareMockedTime();
- robot.checkRequestLoopExtended((i) -> {
- robot.checkShouldNotIgnoreOrientationLoop();
- robot.checkExpectedLoopCount(/* expectedCount */ 0);
- robot.delay();
- });
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
- public void testShouldIgnoreOrientationRequestLoop_returnsTrue() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.createActivityWithComponent();
- robot.prepareIsLetterboxedForFixedOrientationAndAspectRatio(false);
-
- robot.checkRequestLoop((i) -> {
- robot.checkShouldNotIgnoreOrientationLoop();
- robot.checkExpectedLoopCount(/* expectedCount */ i);
- });
- robot.checkShouldIgnoreOrientationLoop();
- robot.checkExpectedLoopCount(/* expectedCount */ MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP);
- });
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
- public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
- runTestScenario((robot) -> {
- robot.prepareIsPolicyForIgnoringRequestedOrientationEnabled(true);
- robot.createActivityWithComponent();
- robot.prepareIsLetterboxedForFixedOrientationAndAspectRatio(false);
-
- robot.checkShouldNotIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
- });
- }
-
- /**
- * Runs a test scenario providing a Robot.
- */
- void runTestScenario(@NonNull Consumer<OrientationCapabilityRobotTest> consumer) {
- spyOn(mWm.mLetterboxConfiguration);
- final OrientationCapabilityRobotTest robot =
- new OrientationCapabilityRobotTest(mWm, mAtm, mSupervisor);
- consumer.accept(robot);
- }
-
- private static class OrientationCapabilityRobotTest {
-
- @NonNull
- private final ActivityTaskManagerService mAtm;
- @NonNull
- private final WindowManagerService mWm;
- @NonNull
- private final ActivityTaskSupervisor mSupervisor;
- @NonNull
- private final LetterboxConfiguration mLetterboxConfiguration;
- @NonNull
- private final TestComponentStack<ActivityRecord> mActivityStack;
- @NonNull
- private final TestComponentStack<Task> mTaskStack;
- @NonNull
- private final CurrentTimeMillisSupplierTest mTestCurrentTimeMillisSupplier;
-
-
- OrientationCapabilityRobotTest(@NonNull WindowManagerService wm,
- @NonNull ActivityTaskManagerService atm,
- @NonNull ActivityTaskSupervisor supervisor) {
- mAtm = atm;
- mWm = wm;
- mSupervisor = supervisor;
- mActivityStack = new TestComponentStack<>();
- mTaskStack = new TestComponentStack<>();
- mLetterboxConfiguration = mWm.mLetterboxConfiguration;
- mTestCurrentTimeMillisSupplier = new CurrentTimeMillisSupplierTest();
- }
-
- void prepareRelaunchingAfterRequestedOrientationChanged(boolean enabled) {
- getTopOrientationCapability().setRelaunchingAfterRequestedOrientationChanged(enabled);
- }
-
- void prepareIsPolicyForIgnoringRequestedOrientationEnabled(boolean enabled) {
- doReturn(enabled).when(mLetterboxConfiguration)
- .isPolicyForIgnoringRequestedOrientationEnabled();
- }
-
- void prepareIsCameraCompatTreatmentEnabled(boolean enabled) {
- doReturn(enabled).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
- }
-
- void prepareIsCameraCompatTreatmentEnabledAtBuildTime(boolean enabled) {
- doReturn(enabled).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabledAtBuildTime();
- }
-
- void prepareIsTreatmentEnabledForTopActivity(boolean enabled) {
- final DisplayRotationCompatPolicy displayPolicy = mActivityStack.top()
- .mDisplayContent.mDisplayRotationCompatPolicy;
- spyOn(displayPolicy);
- doReturn(enabled).when(displayPolicy)
- .isTreatmentEnabledForActivity(eq(mActivityStack.top()));
- }
-
- // Useful to reduce timeout during tests
- void prepareMockedTime() {
- getTopOrientationCapability().mOrientationCapabilityState.mCurrentTimeMillisSupplier =
- mTestCurrentTimeMillisSupplier;
- }
-
- void delay() {
- mTestCurrentTimeMillisSupplier.delay(SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS);
- }
-
- void enableProperty(@NonNull String propertyName) {
- setPropertyValue(propertyName, /* enabled */ true);
- }
-
- void disableProperty(@NonNull String propertyName) {
- setPropertyValue(propertyName, /* enabled */ false);
- }
-
- void prepareIsLetterboxedForFixedOrientationAndAspectRatio(boolean enabled) {
- spyOn(mActivityStack.top());
- doReturn(enabled).when(mActivityStack.top())
- .isLetterboxedForFixedOrientationAndAspectRatio();
- }
-
- void createActivityWithComponent() {
- createActivityWithComponentInNewTask(/* inNewTask */ mTaskStack.isEmpty());
- }
-
- void createActivityWithComponentInNewTask() {
- createActivityWithComponentInNewTask(/* inNewTask */ true);
- }
-
- private void createActivityWithComponentInNewTask(boolean inNewTask) {
- if (inNewTask) {
- createNewTask();
- }
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setOnTop(true)
- .setTask(mTaskStack.top())
- // Set the component to be that of the test class in order
- // to enable compat changes
- .setComponent(ComponentName.createRelative(mAtm.mContext,
- com.android.server.wm.LetterboxUiControllerTest.class.getName()))
- .build();
- mActivityStack.push(activity);
- }
-
- void checkShouldIgnoreRequestedOrientation(
- @Configuration.Orientation int expectedOrientation) {
- assertTrue(getTopOrientationCapability()
- .shouldIgnoreRequestedOrientation(expectedOrientation));
- }
-
- void checkShouldNotIgnoreRequestedOrientation(
- @Configuration.Orientation int expectedOrientation) {
- assertFalse(getTopOrientationCapability()
- .shouldIgnoreRequestedOrientation(expectedOrientation));
- }
-
- void checkExpectedLoopCount(int expectedCount) {
- assertEquals(expectedCount, getTopOrientationCapability()
- .getSetOrientationRequestCounter());
- }
-
- void checkShouldNotIgnoreOrientationLoop() {
- assertFalse(getTopOrientationCapability().shouldIgnoreOrientationRequestLoop());
- }
-
- void checkShouldIgnoreOrientationLoop() {
- assertTrue(getTopOrientationCapability().shouldIgnoreOrientationRequestLoop());
- }
-
- void checkRequestLoop(IntConsumer consumer) {
- for (int i = 0; i < MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
- consumer.accept(i);
- }
- }
-
- void checkRequestLoopExtended(IntConsumer consumer) {
- for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
- consumer.accept(i);
- }
- }
-
- private AppCompatOrientationCapability getTopOrientationCapability() {
- return mActivityStack.top().mAppCompatController.getAppCompatCapability()
- .getAppCompatOrientationCapability();
- }
-
- private void createNewTask() {
- final DisplayContent displayContent = new TestDisplayContent
- .Builder(mAtm, /* dw */ 1000, /* dh */ 2000).build();
- final Task newTask = new TaskBuilder(mSupervisor).setDisplay(displayContent).build();
- mTaskStack.push(newTask);
- }
-
- private void setPropertyValue(@NonNull String propertyName, boolean enabled) {
- PackageManager.Property property = new PackageManager.Property(propertyName,
- /* value */ enabled, /* packageName */ "",
- /* className */ "");
- PackageManager pm = mWm.mContext.getPackageManager();
- spyOn(pm);
- try {
- doReturn(property).when(pm).getProperty(eq(propertyName), anyString());
- } catch (PackageManager.NameNotFoundException e) {
- fail(e.getLocalizedMessage());
- }
- }
-
- private static class CurrentTimeMillisSupplierTest implements LongSupplier {
-
- private long mCurrenTimeMillis = System.currentTimeMillis();
-
- @Override
- public long getAsLong() {
- return mCurrenTimeMillis;
- }
-
- public void delay(long delay) {
- mCurrenTimeMillis += delay;
- }
- }
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
new file mode 100644
index 0000000..1720b64
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2024 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.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.AppCompatOrientationOverrides.OrientationOverridesState.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
+import static com.android.server.wm.AppCompatOrientationOverrides.OrientationOverridesState.SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.content.res.Configuration;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.wm.utils.CurrentTimeMillisSupplierFake;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+import java.util.function.IntConsumer;
+
+/**
+ * Test class for {@link AppCompatOrientationOverrides}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatOrientationOverridesTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatOrientationOverridesTest extends WindowTestsBase {
+
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+ public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+ public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.applyOnConf((c) -> {
+ c.enableCameraCompatTreatment(true);
+ c.enableCameraCompatTreatmentAtBuildTime(true);
+ c.enablePolicyForIgnoringRequestedOrientation(true);
+ });
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponentInNewTask();
+ a.enableTreatmentForTopActivity(true);
+ });
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(false);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.prop().enable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+ public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
+ throws Exception {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.prop().disable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+
+ robot.activity().createActivityWithComponent();
+ robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ @Test
+ public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+ });
+ robot.checkRequestLoopExtended((i) -> {
+ robot.checkShouldNotIgnoreOrientationLoop();
+ robot.checkExpectedLoopCount(/* expectedCount */ 0);
+ });
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_propertyIsFalseAndOverride_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.prop().disable(
+ PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+ });
+ robot.checkRequestLoopExtended((i) -> {
+ robot.checkShouldNotIgnoreOrientationLoop();
+ robot.checkExpectedLoopCount(/* expectedCount */ 0);
+ });
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(true);
+ });
+ robot.checkRequestLoopExtended((i) -> {
+ robot.checkShouldNotIgnoreOrientationLoop();
+ robot.checkExpectedLoopCount(/* expectedCount */ i);
+ });
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+ });
+
+ robot.checkShouldNotIgnoreOrientationLoop();
+ robot.checkExpectedLoopCount(/* expectedCount */ 0);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+ });
+
+ robot.prepareMockedTime();
+ robot.checkRequestLoopExtended((i) -> {
+ robot.checkShouldNotIgnoreOrientationLoop();
+ robot.checkExpectedLoopCount(/* expectedCount */ 0);
+ robot.delay();
+ });
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_returnsTrue() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+ });
+
+ robot.checkRequestLoop((i) -> {
+ robot.checkShouldNotIgnoreOrientationLoop();
+ robot.checkExpectedLoopCount(/* expectedCount */ i);
+ });
+ robot.checkShouldIgnoreOrientationLoop();
+ robot.checkExpectedLoopCount(/* expectedCount */ MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP);
+ });
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+ public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
+ runTestScenario((robot) -> {
+ robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+ });
+
+ robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+ /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+ });
+ }
+
+ /**
+ * Runs a test scenario providing a Robot.
+ */
+ void runTestScenario(@NonNull Consumer<OrientationOverridesRobotTest> consumer) {
+ spyOn(mWm.mLetterboxConfiguration);
+ final OrientationOverridesRobotTest robot =
+ new OrientationOverridesRobotTest(mWm, mAtm, mSupervisor);
+ consumer.accept(robot);
+ }
+
+ private static class OrientationOverridesRobotTest extends AppCompatRobotBase {
+
+ @NonNull
+ private final CurrentTimeMillisSupplierFake mTestCurrentTimeMillisSupplier;
+
+ OrientationOverridesRobotTest(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm,
+ @NonNull ActivityTaskSupervisor supervisor) {
+ super(wm, atm, supervisor);
+ mTestCurrentTimeMillisSupplier = new CurrentTimeMillisSupplierFake();
+ }
+
+ void prepareRelaunchingAfterRequestedOrientationChanged(boolean enabled) {
+ getTopOrientationOverrides().setRelaunchingAfterRequestedOrientationChanged(enabled);
+ }
+
+ // Useful to reduce timeout during tests
+ void prepareMockedTime() {
+ getTopOrientationOverrides().mOrientationOverridesState.mCurrentTimeMillisSupplier =
+ mTestCurrentTimeMillisSupplier;
+ }
+
+ void delay() {
+ mTestCurrentTimeMillisSupplier.delay(SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS);
+ }
+
+ void checkShouldIgnoreRequestedOrientation(boolean expected,
+ @Configuration.Orientation int requestedOrientation) {
+ assertEquals(expected, getTopOrientationOverrides()
+ .shouldIgnoreRequestedOrientation(requestedOrientation));
+ }
+
+ void checkExpectedLoopCount(int expectedCount) {
+ assertEquals(expectedCount, getTopOrientationOverrides()
+ .getSetOrientationRequestCounter());
+ }
+
+ void checkShouldNotIgnoreOrientationLoop() {
+ assertFalse(getTopOrientationOverrides().shouldIgnoreOrientationRequestLoop());
+ }
+
+ void checkShouldIgnoreOrientationLoop() {
+ assertTrue(getTopOrientationOverrides().shouldIgnoreOrientationRequestLoop());
+ }
+
+ void checkRequestLoop(IntConsumer consumer) {
+ for (int i = 0; i < MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+ consumer.accept(i);
+ }
+ }
+
+ void checkRequestLoopExtended(IntConsumer consumer) {
+ for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+ consumer.accept(i);
+ }
+ }
+
+ private AppCompatOrientationOverrides getTopOrientationOverrides() {
+ return activity().top().mAppCompatController.getAppCompatOverrides()
+ .getAppCompatOrientationOverrides();
+ }
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
index 2260999..9885a2d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
@@ -34,24 +34,16 @@
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import android.compat.testing.PlatformCompatChangeRule;
-import android.content.ComponentName;
import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
import android.platform.test.annotations.Presubmit;
import androidx.annotation.NonNull;
-import com.android.server.wm.utils.TestComponentStack;
-
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import org.junit.Assert;
@@ -87,7 +79,7 @@
@EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_returnsUser() {
runTestScenarioWithActivity((robot) -> {
- robot.configureSetIgnoreOrientationRequest(true);
+ robot.activity().setIgnoreOrientationRequest(true);
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_USER);
});
@@ -97,9 +89,11 @@
@EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_optOut_isUnchanged() {
runTestScenario((robot) -> {
- robot.disableProperty(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
- robot.createActivityWithComponent();
- robot.configureSetIgnoreOrientationRequest(true);
+ robot.prop().disable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setIgnoreOrientationRequest(true);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_PORTRAIT);
@@ -110,12 +104,13 @@
@EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
public void testOverrideOrientationIfNeeded_fullscreenOverrides_optOutSystem_returnsUser() {
runTestScenario((robot) -> {
- robot.disableProperty(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
- robot.configureIsUserAppAspectRatioFullscreenEnabled(true);
-
- robot.createActivityWithComponent();
- robot.configureSetIgnoreOrientationRequest(true);
- robot.prepareGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN);
+ robot.prop().disable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+ robot.conf().enableUserAppAspectRatioFullscreen(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setIgnoreOrientationRequest(true);
+ a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_USER);
@@ -126,12 +121,13 @@
@EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
public void testOverrideOrientationIfNeeded_fullscreenOverrides_optOutUser_returnsUser() {
runTestScenario((robot) -> {
- robot.disableProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE);
- robot.configureIsUserAppAspectRatioFullscreenEnabled(true);
-
- robot.createActivityWithComponent();
- robot.configureSetIgnoreOrientationRequest(true);
- robot.prepareGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN);
+ robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE);
+ robot.conf().enableUserAppAspectRatioFullscreen(true);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setIgnoreOrientationRequest(true);
+ a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_USER);
@@ -143,7 +139,7 @@
public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_returnsUnchanged()
throws Exception {
runTestScenarioWithActivity((robot) -> {
- robot.configureSetIgnoreOrientationRequest(false);
+ robot.activity().setIgnoreOrientationRequest(false);
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_PORTRAIT);
@@ -154,11 +150,13 @@
@EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
public void testOverrideOrientationIfNeeded_fullscreenAndUserOverrideEnabled_isUnchanged() {
runTestScenario((robot) -> {
- robot.prepareIsUserAppAspectRatioSettingsEnabled(true);
+ robot.conf().enableUserAppAspectRatioSettings(true);
- robot.createActivityWithComponent();
- robot.configureSetIgnoreOrientationRequest(true);
- robot.prepareGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2);
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setIgnoreOrientationRequest(true);
+ a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_PORTRAIT);
@@ -249,9 +247,9 @@
public void testOverrideOrientationIfNeeded_propertyIsFalse_isUnchanged()
throws Exception {
runTestScenario((robot) -> {
- robot.disableProperty(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+ robot.prop().disable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
- robot.createActivityWithComponent();
+ robot.activity().createActivityWithComponent();
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
/* expected */ SCREEN_ORIENTATION_UNSPECIFIED);
@@ -263,11 +261,14 @@
OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
public void testOverrideOrientationIfNeeded_whenCameraNotActive_isUnchanged() {
runTestScenario((robot) -> {
- robot.configureIsCameraCompatTreatmentEnabled(true);
- robot.configureIsCameraCompatTreatmentEnabledAtBuildTime(true);
-
- robot.createActivityWithComponentInNewTask();
- robot.prepareIsTopActivityEligibleForOrientationOverride(false);
+ robot.applyOnConf((c)-> {
+ c.enableCameraCompatTreatment(true);
+ c.enableCameraCompatTreatmentAtBuildTime(true);
+ });
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponentInNewTask();
+ a.setTopActivityEligibleForOrientationOverride(false);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
/* expected */ SCREEN_ORIENTATION_UNSPECIFIED);
@@ -279,11 +280,14 @@
OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
public void testOverrideOrientationIfNeeded_whenCameraActive_returnsPortrait() {
runTestScenario((robot) -> {
- robot.configureIsCameraCompatTreatmentEnabled(true);
- robot.configureIsCameraCompatTreatmentEnabledAtBuildTime(true);
-
- robot.createActivityWithComponentInNewTask();
- robot.prepareIsTopActivityEligibleForOrientationOverride(true);
+ robot.applyOnConf((c) -> {
+ c.enableCameraCompatTreatment(true);
+ c.enableCameraCompatTreatmentAtBuildTime(true);
+ });
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponentInNewTask();
+ a.setTopActivityEligibleForOrientationOverride(true);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
/* expected */ SCREEN_ORIENTATION_PORTRAIT);
@@ -293,8 +297,10 @@
@Test
public void testOverrideOrientationIfNeeded_userFullscreenOverride_returnsUser() {
runTestScenarioWithActivity((robot) -> {
- robot.prepareShouldApplyUserFullscreenOverride(true);
- robot.configureSetIgnoreOrientationRequest(true);
+ robot.applyOnActivity((a) -> {
+ a.setShouldApplyUserFullscreenOverride(true);
+ a.setIgnoreOrientationRequest(true);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
/* expected */ SCREEN_ORIENTATION_USER);
@@ -304,11 +310,14 @@
@Test
public void testOverrideOrientationIfNeeded_fullscreenOverride_cameraActivity_unchanged() {
runTestScenario((robot) -> {
- robot.configureIsCameraCompatTreatmentEnabled(true);
- robot.configureIsCameraCompatTreatmentEnabledAtBuildTime(true);
-
- robot.createActivityWithComponentInNewTask();
- robot.configureIsTopActivityCameraActive(false);
+ robot.applyOnConf((c) -> {
+ c.enableCameraCompatTreatment(true);
+ c.enableCameraCompatTreatmentAtBuildTime(true);
+ });
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponentInNewTask();
+ a.setTopActivityCameraActive(false);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_PORTRAIT);
@@ -318,8 +327,10 @@
@Test
public void testOverrideOrientationIfNeeded_respectOrientationRequestOverUserFullScreen() {
runTestScenarioWithActivity((robot) -> {
- robot.prepareShouldApplyUserFullscreenOverride(true);
- robot.configureSetIgnoreOrientationRequest(false);
+ robot.applyOnActivity((a) -> {
+ a.setShouldApplyUserFullscreenOverride(true);
+ a.setIgnoreOrientationRequest(false);
+ });
robot.checkOverrideOrientationIsNot(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
/* notExpected */ SCREEN_ORIENTATION_USER);
@@ -330,8 +341,10 @@
@EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
public void testOverrideOrientationIfNeeded_userFullScreenOverrideOverSystem_returnsUser() {
runTestScenarioWithActivity((robot) -> {
- robot.prepareShouldApplyUserFullscreenOverride(true);
- robot.configureSetIgnoreOrientationRequest(true);
+ robot.applyOnActivity((a) -> {
+ a.setShouldApplyUserFullscreenOverride(true);
+ a.setIgnoreOrientationRequest(true);
+ });
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_USER);
@@ -342,9 +355,10 @@
@EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
public void testOverrideOrientationIfNeeded_respectOrientationReqOverUserFullScreenAndSystem() {
runTestScenarioWithActivity((robot) -> {
- robot.prepareShouldApplyUserFullscreenOverride(true);
- robot.configureSetIgnoreOrientationRequest(false);
-
+ robot.applyOnActivity((a) -> {
+ a.setShouldApplyUserFullscreenOverride(true);
+ a.setIgnoreOrientationRequest(false);
+ });
robot.checkOverrideOrientationIsNot(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* notExpected */ SCREEN_ORIENTATION_USER);
});
@@ -353,7 +367,7 @@
@Test
public void testOverrideOrientationIfNeeded_userFullScreenOverrideDisabled_returnsUnchanged() {
runTestScenarioWithActivity((robot) -> {
- robot.prepareShouldApplyUserFullscreenOverride(false);
+ robot.activity().setShouldApplyUserFullscreenOverride(false);
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
/* expected */ SCREEN_ORIENTATION_PORTRAIT);
@@ -363,7 +377,7 @@
@Test
public void testOverrideOrientationIfNeeded_userAspectRatioApplied_unspecifiedOverridden() {
runTestScenarioWithActivity((robot) -> {
- robot.prepareShouldApplyUserMinAspectRatioOverride(true);
+ robot.activity().setShouldApplyUserMinAspectRatioOverride(true);
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
/* expected */ SCREEN_ORIENTATION_PORTRAIT);
@@ -377,7 +391,7 @@
@Test
public void testOverrideOrientationIfNeeded_userAspectRatioNotApplied_isUnchanged() {
runTestScenarioWithActivity((robot) -> {
- robot.prepareShouldApplyUserFullscreenOverride(false);
+ robot.activity().setShouldApplyUserFullscreenOverride(false);
robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
/* expected */ SCREEN_ORIENTATION_UNSPECIFIED);
@@ -410,99 +424,24 @@
consumer.accept(robot);
}
- private static class OrientationPolicyRobotTest {
+ private static class OrientationPolicyRobotTest extends AppCompatRobotBase{
- @NonNull
- private final ActivityTaskManagerService mAtm;
- @NonNull
private final WindowManagerService mWm;
- @NonNull
- private final LetterboxConfiguration mLetterboxConfiguration;
- @NonNull
- private final TestComponentStack<ActivityRecord> mActivityStack;
- @NonNull
- private final TestComponentStack<Task> mTaskStack;
-
- @NonNull
- private final ActivityTaskSupervisor mSupervisor;
OrientationPolicyRobotTest(@NonNull WindowManagerService wm,
@NonNull ActivityTaskManagerService atm,
@NonNull ActivityTaskSupervisor supervisor,
boolean withActivity) {
- mAtm = atm;
+ super(wm, atm, supervisor);
mWm = wm;
spyOn(mWm);
- mSupervisor = supervisor;
- mActivityStack = new TestComponentStack<>();
- mTaskStack = new TestComponentStack<>();
- mLetterboxConfiguration = mWm.mLetterboxConfiguration;
if (withActivity) {
- createActivityWithComponent();
+ activity().createActivityWithComponent();
}
}
- void configureSetIgnoreOrientationRequest(boolean enabled) {
- mActivityStack.top().mDisplayContent.setIgnoreOrientationRequest(enabled);
- }
-
- void configureIsUserAppAspectRatioFullscreenEnabled(boolean enabled) {
- doReturn(enabled).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
- }
-
- void configureIsCameraCompatTreatmentEnabled(boolean enabled) {
- doReturn(enabled).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
- }
-
- void configureIsCameraCompatTreatmentEnabledAtBuildTime(boolean enabled) {
- doReturn(enabled).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabledAtBuildTime();
- }
-
- void prepareGetUserMinAspectRatioOverrideCode(int orientation) {
- spyOn(mActivityStack.top().mLetterboxUiController);
- doReturn(orientation).when(mActivityStack.top()
- .mLetterboxUiController).getUserMinAspectRatioOverrideCode();
- }
-
- void prepareShouldApplyUserFullscreenOverride(boolean enabled) {
- spyOn(mActivityStack.top().mLetterboxUiController);
- doReturn(enabled).when(mActivityStack.top()
- .mLetterboxUiController).shouldApplyUserFullscreenOverride();
- }
-
- void prepareShouldApplyUserMinAspectRatioOverride(boolean enabled) {
- spyOn(mActivityStack.top().mLetterboxUiController);
- doReturn(enabled).when(mActivityStack.top()
- .mLetterboxUiController).shouldApplyUserMinAspectRatioOverride();
- }
-
- void prepareIsUserAppAspectRatioSettingsEnabled(boolean enabled) {
- doReturn(enabled).when(mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
- }
-
- void prepareIsTopActivityEligibleForOrientationOverride(boolean enabled) {
- final DisplayRotationCompatPolicy displayPolicy =
- mActivityStack.top().mDisplayContent.mDisplayRotationCompatPolicy;
- spyOn(displayPolicy);
- doReturn(enabled).when(displayPolicy)
- .isActivityEligibleForOrientationOverride(eq(mActivityStack.top()));
- }
-
- void configureIsTopActivityCameraActive(boolean enabled) {
- final DisplayRotationCompatPolicy displayPolicy =
- mActivityStack.top().mDisplayContent.mDisplayRotationCompatPolicy;
- spyOn(displayPolicy);
- doReturn(enabled).when(displayPolicy)
- .isCameraActive(eq(mActivityStack.top()), /* mustBeFullscreen= */ eq(true));
- }
-
- void disableProperty(@NonNull String propertyName) {
- setPropertyValue(propertyName, /* enabled */ false);
- }
-
int overrideOrientationIfNeeded(@ActivityInfo.ScreenOrientation int candidate) {
- return mActivityStack.top().mAppCompatController.getOrientationPolicy()
+ return activity().top().mAppCompatController.getOrientationPolicy()
.overrideOrientationIfNeeded(candidate);
}
@@ -519,52 +458,5 @@
@ActivityInfo.ScreenOrientation int notExpected) {
Assert.assertNotEquals(notExpected, overrideOrientationIfNeeded(candidate));
}
-
- private void createActivityWithComponent() {
- if (mTaskStack.isEmpty()) {
- final DisplayContent displayContent = new TestDisplayContent
- .Builder(mAtm, /* dw */ 1000, /* dh */ 2000).build();
- final Task task = new TaskBuilder(mSupervisor).setDisplay(displayContent).build();
- mTaskStack.push(task);
- }
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setOnTop(true)
- .setTask(mTaskStack.top())
- // Set the component to be that of the test class in order
- // to enable compat changes
- .setComponent(ComponentName.createRelative(mAtm.mContext,
- com.android.server.wm.LetterboxUiControllerTest.class.getName()))
- .build();
- mActivityStack.push(activity);
- }
-
- private void createActivityWithComponentInNewTask() {
- final DisplayContent displayContent = new TestDisplayContent
- .Builder(mAtm, /* dw */ 1000, /* dh */ 2000).build();
- final Task task = new TaskBuilder(mSupervisor).setDisplay(displayContent).build();
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setOnTop(true)
- .setTask(task)
- // Set the component to be that of the test class in order
- // to enable compat changes
- .setComponent(ComponentName.createRelative(mAtm.mContext,
- com.android.server.wm.LetterboxUiControllerTest.class.getName()))
- .build();
- mTaskStack.push(task);
- mActivityStack.push(activity);
- }
-
- private void setPropertyValue(@NonNull String propertyName, boolean enabled) {
- PackageManager.Property property = new PackageManager.Property(propertyName,
- /* value */ enabled, /* packageName */ "",
- /* className */ "");
- PackageManager pm = mWm.mContext.getPackageManager();
- spyOn(pm);
- try {
- doReturn(property).when(pm).getProperty(eq(propertyName), anyString());
- } catch (PackageManager.NameNotFoundException e) {
- fail(e.getLocalizedMessage());
- }
- }
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java
new file mode 100644
index 0000000..de16e38
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 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 androidx.annotation.NonNull;
+
+import java.util.function.Consumer;
+
+/**
+ * Base class for the Robots related to App Compat tests.
+ */
+abstract class AppCompatRobotBase {
+
+ private static final int DEFAULT_DISPLAY_WIDTH = 1000;
+ private static final int DEFAULT_DISPLAY_HEIGHT = 2000;
+
+ @NonNull
+ private final AppCompatActivityRobot mActivityRobot;
+ @NonNull
+ private final AppCompatLetterboxConfigurationRobot mConfigurationRobot;
+ @NonNull
+ private final AppCompatComponentPropRobot mOptPropRobot;
+
+ AppCompatRobotBase(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm,
+ @NonNull ActivityTaskSupervisor supervisor,
+ int displayWidth, int displayHeight) {
+ mActivityRobot = new AppCompatActivityRobot(wm, atm, supervisor,
+ displayWidth, displayHeight);
+ mConfigurationRobot =
+ new AppCompatLetterboxConfigurationRobot(wm.mLetterboxConfiguration);
+ mOptPropRobot = new AppCompatComponentPropRobot(wm);
+ }
+
+ AppCompatRobotBase(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm,
+ @NonNull ActivityTaskSupervisor supervisor) {
+ this(wm, atm, supervisor, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
+ }
+
+ @NonNull
+ AppCompatLetterboxConfigurationRobot conf() {
+ return mConfigurationRobot;
+ }
+
+ @NonNull
+ void applyOnConf(@NonNull Consumer<AppCompatLetterboxConfigurationRobot> consumer) {
+ consumer.accept(mConfigurationRobot);
+ }
+
+ @NonNull
+ AppCompatActivityRobot activity() {
+ return mActivityRobot;
+ }
+
+ @NonNull
+ void applyOnActivity(@NonNull Consumer<AppCompatActivityRobot> consumer) {
+ consumer.accept(mActivityRobot);
+ }
+
+ @NonNull
+ AppCompatComponentPropRobot prop() {
+ return mOptPropRobot;
+ }
+
+ @NonNull
+ void applyOnProp(@NonNull Consumer<AppCompatComponentPropRobot> consumer) {
+ consumer.accept(mOptPropRobot);
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatTransparentActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatTransparentActivityRobot.java
new file mode 100644
index 0000000..3cfbb9e
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatTransparentActivityRobot.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2024 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.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.app.WindowConfiguration;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.junit.Assert;
+
+import java.util.function.Consumer;
+
+/**
+ * Robot implementation for {@link ActivityRecord} when dealing with transparent activities.
+ */
+class AppCompatTransparentActivityRobot {
+
+ @Nullable
+ private WindowConfiguration mTopActivityWindowConfiguration;
+
+ @NonNull
+ private final AppCompatActivityRobot mActivityRobot;
+
+ AppCompatTransparentActivityRobot(@NonNull AppCompatActivityRobot activityRobot) {
+ mActivityRobot = activityRobot;
+ }
+
+ @NonNull
+ AppCompatActivityRobot activity() {
+ return mActivityRobot;
+ }
+
+ @NonNull
+ void applyOnActivity(@NonNull Consumer<AppCompatActivityRobot> consumer) {
+ consumer.accept(mActivityRobot);
+ }
+
+ void launchTransparentActivity() {
+ mActivityRobot.launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
+ SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
+ /* withComponent */ false, /* addToTask */ false);
+ }
+
+ void launchTransparentActivityInTask() {
+ mActivityRobot.launchActivity(/*minAspectRatio */ -1,
+ /* maxAspectRatio */ -1, SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
+ /* withComponent */ false, /* addToTask */true);
+ }
+
+ void launchOpaqueActivityInTask() {
+ mActivityRobot.launchActivity(/*minAspectRatio */ -1,
+ /* maxAspectRatio */ -1, SCREEN_ORIENTATION_PORTRAIT, /* transparent */ false,
+ /* withComponent */ false, /* addToTask */true);
+ }
+
+ void forceChangeInTopActivityConfiguration() {
+ activity().applyToTopActivity((topActivity) -> {
+ final Configuration requestedConfig =
+ topActivity.getRequestedOverrideConfiguration();
+ mTopActivityWindowConfiguration = requestedConfig.windowConfiguration;
+ mTopActivityWindowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
+ mTopActivityWindowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ mTopActivityWindowConfiguration.setAlwaysOnTop(true);
+ topActivity.onRequestedOverrideConfigurationChanged(requestedConfig);
+ });
+ }
+
+ void checkTopActivityConfigurationConfiguration() {
+ activity().applyToTopActivity((topActivity) -> {
+ // The original override of WindowConfiguration should keep.
+ assertEquals(ACTIVITY_TYPE_STANDARD, topActivity.getActivityType());
+ assertEquals(WINDOWING_MODE_MULTI_WINDOW,
+ mTopActivityWindowConfiguration.getWindowingMode());
+ assertTrue(mTopActivityWindowConfiguration.isAlwaysOnTop());
+ // Unless display is going to be rotated, it should always inherit from parent.
+ assertEquals(ROTATION_UNDEFINED,
+ mTopActivityWindowConfiguration.getDisplayRotation());
+ });
+ }
+
+ void checkTopActivityTransparentPolicyStateIsRunning(boolean running) {
+ assertEquals(running,
+ activity().top().mAppCompatController.getTransparentPolicy().isRunning());
+ }
+
+ void checkTopActivityTransparentPolicyStartInvoked() {
+ activity().applyToTopActivity((topActivity) -> {
+ verify(topActivity.mAppCompatController.getTransparentPolicy()).start();
+ });
+ }
+
+ void checkTopActivityTransparentPolicyStartNotInvoked() {
+ verify(activity().top().mAppCompatController.getTransparentPolicy(), never()).start();
+ }
+
+ void checkTopActivityTransparentPolicyStopInvoked() {
+ verify(activity().top().mAppCompatController.getTransparentPolicy()).stop();
+ }
+
+ void checkTopActivityTransparentPolicyStopNotInvoked() {
+ verify(activity().top().mAppCompatController.getTransparentPolicy(), never()).stop();
+ }
+
+ void checkTopActivityHasInheritedBoundsFrom(int fromTop) {
+ final ActivityRecord topActivity = activity().top();
+ final ActivityRecord otherActivity = activity().getFromTop(/* fromTop */ fromTop);
+ final Rect opaqueBounds = otherActivity.getConfiguration().windowConfiguration
+ .getBounds();
+ final Rect translucentRequestedBounds = topActivity.getRequestedOverrideBounds();
+ Assert.assertEquals(opaqueBounds, translucentRequestedBounds);
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
index b3f1502..564c29f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
@@ -245,8 +245,8 @@
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- doReturn(false).when(
- mActivity.mLetterboxUiController).shouldRefreshActivityForCameraCompat();
+ doReturn(false).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+ .shouldRefreshActivityForCameraCompat();
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
callOnActivityConfigurationChanging(mActivity);
@@ -271,7 +271,7 @@
public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- doReturn(true).when(mActivity.mLetterboxUiController)
+ doReturn(true).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
.shouldRefreshActivityViaPauseForCameraCompat();
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -305,6 +305,7 @@
.build();
spyOn(mActivity.mLetterboxUiController);
+ spyOn(mActivity.mAppCompatController.getAppCompatCameraOverrides());
spyOn(mActivity.info);
doReturn(mActivity).when(mDisplayContent).topRunningActivity(anyBoolean());
@@ -315,12 +316,14 @@
private void assertInCameraCompatMode() {
assertNotEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE,
- mActivity.mLetterboxUiController.getFreeformCameraCompatMode());
+ mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .getFreeformCameraCompatMode());
}
private void assertNotInCameraCompatMode() {
assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE,
- mActivity.mLetterboxUiController.getFreeformCameraCompatMode());
+ mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .getFreeformCameraCompatMode());
}
private void assertActivityRefreshRequested(boolean refreshRequested) throws Exception {
@@ -329,8 +332,8 @@
private void assertActivityRefreshRequested(boolean refreshRequested,
boolean cycleThroughStop) throws Exception {
- verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0))
- .setIsRefreshRequested(true);
+ verify(mActivity.mAppCompatController.getAppCompatCameraOverrides(),
+ times(refreshRequested ? 1 : 0)).setIsRefreshRequested(true);
final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain(mActivity.token,
cycleThroughStop ? ON_STOP : ON_PAUSE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
index c65371f..d7814ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
@@ -266,7 +266,7 @@
public void testTreatmentDisabledPerApp_noForceRotationOrRefresh()
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- doReturn(false).when(mActivity.mLetterboxUiController)
+ doReturn(false).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
.shouldForceRotateForCameraCompat();
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -468,8 +468,8 @@
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- doReturn(false).when(
- mActivity.mLetterboxUiController).shouldRefreshActivityForCameraCompat();
+ doReturn(false).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+ .shouldRefreshActivityForCameraCompat();
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
@@ -494,8 +494,9 @@
public void testOnActivityConfigurationChanging_displayRotationNotChanging_noRefresh()
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- doReturn(false).when(mActivity.mLetterboxUiController)
- .isCameraCompatSplitScreenAspectRatioAllowed();
+ doReturn(false).when(mActivity
+ .mAppCompatController.getAppCompatCameraOverrides())
+ .isCameraCompatSplitScreenAspectRatioAllowed();
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ false);
@@ -507,7 +508,7 @@
public void testOnActivityConfigurationChanging_splitScreenAspectRatioAllowed_refresh()
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- doReturn(true).when(mActivity.mLetterboxUiController)
+ doReturn(true).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
.isCameraCompatSplitScreenAspectRatioAllowed();
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -533,7 +534,7 @@
public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- doReturn(true).when(mActivity.mLetterboxUiController)
+ doReturn(true).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
.shouldRefreshActivityViaPauseForCameraCompat();
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -597,6 +598,7 @@
spyOn(mActivity.mAtmService.getLifecycleManager());
spyOn(mActivity.mLetterboxUiController);
+ spyOn(mActivity.mAppCompatController.getAppCompatCameraOverrides());
doReturn(mActivity).when(mDisplayContent).topRunningActivity(anyBoolean());
doReturn(naturalOrientation).when(mDisplayContent).getNaturalOrientation();
@@ -608,8 +610,8 @@
private void assertActivityRefreshRequested(boolean refreshRequested,
boolean cycleThroughStop) throws Exception {
- verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0))
- .setIsRefreshRequested(true);
+ verify(mActivity.mAppCompatController.getAppCompatCameraOverrides(),
+ times(refreshRequested ? 1 : 0)).setIsRefreshRequested(true);
final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain(mActivity.token,
cycleThroughStop ? ON_STOP : ON_PAUSE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
index 7d9fdd5..3fcf304 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -24,9 +24,12 @@
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import static org.testng.Assert.assertFalse;
import android.annotation.Nullable;
@@ -55,6 +58,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
+import java.util.function.Consumer;
/**
* Tests for the {@link DisplayWindowSettingsProvider} class.
@@ -128,9 +132,8 @@
// Update settings with new value, should trigger write to injector.
DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
- SettingsEntry overrideSettings = provider.getOverrideSettings(mPrimaryDisplayInfo);
- overrideSettings.mForcedDensity = 200;
- provider.updateOverrideSettings(mPrimaryDisplayInfo, overrideSettings);
+ updateOverrideSettings(provider, mPrimaryDisplayInfo,
+ overrideSettings -> overrideSettings.mForcedDensity = 200);
assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
// Verify that display identifier was updated.
@@ -167,7 +170,7 @@
}
@Test
- public void testReadingDisplaySettingsFromStorage_secondayVendorDisplaySettingsLocation() {
+ public void testReadingDisplaySettingsFromStorage_secondaryVendorDisplaySettingsLocation() {
final String displayIdentifier = mSecondaryDisplay.getDisplayInfo().uniqueId;
prepareSecondaryDisplaySettings(displayIdentifier);
@@ -216,11 +219,11 @@
// Write some settings to storage.
DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
- SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
- overrideSettings.mShouldShowSystemDecors = true;
- overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
- overrideSettings.mDontMoveToTop = true;
- provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+ updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+ overrideSettings.mShouldShowSystemDecors = true;
+ overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
+ overrideSettings.mDontMoveToTop = true;
+ });
assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
// Verify that settings were stored correctly.
@@ -235,6 +238,29 @@
}
@Test
+ public void testWritingDisplaySettingsToStorage_secondaryUserDisplaySettingsLocation() {
+ final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
+ mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
+ final DisplayInfo displayInfo = mPrimaryDisplay.getDisplayInfo();
+ final TestStorage secondaryUserOverrideSettingsStorage = new TestStorage();
+ final SettingsEntry expectedSettings = new SettingsEntry();
+ expectedSettings.mForcedDensity = 356;
+
+ // Write some settings to storage from default user.
+ updateOverrideSettings(provider, displayInfo, settings -> settings.mForcedDensity = 356);
+ assertThat(mOverrideSettingsStorage.wasWriteSuccessful()).isTrue();
+
+ // Now switch to secondary user override settings and write some settings.
+ provider.setOverrideSettingsStorage(secondaryUserOverrideSettingsStorage);
+ updateOverrideSettings(provider, displayInfo, settings -> settings.mForcedDensity = 420);
+ assertThat(secondaryUserOverrideSettingsStorage.wasWriteSuccessful()).isTrue();
+
+ // Switch back to primary and assert default user settings remain unchanged.
+ provider.setOverrideSettingsStorage(mOverrideSettingsStorage);
+ assertThat(provider.getOverrideSettings(displayInfo)).isEqualTo(expectedSettings);
+ }
+
+ @Test
public void testDoNotWriteVirtualDisplaySettingsToStorage() throws Exception {
final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
secondaryDisplayInfo.type = TYPE_VIRTUAL;
@@ -242,11 +268,11 @@
// No write to storage on virtual display change.
final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
- final SettingsEntry virtualSettings = provider.getOverrideSettings(secondaryDisplayInfo);
- virtualSettings.mShouldShowSystemDecors = true;
- virtualSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
- virtualSettings.mDontMoveToTop = true;
- provider.updateOverrideSettings(secondaryDisplayInfo, virtualSettings);
+ updateOverrideSettings(provider, secondaryDisplayInfo, virtualSettings -> {
+ virtualSettings.mShouldShowSystemDecors = true;
+ virtualSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
+ virtualSettings.mDontMoveToTop = true;
+ });
assertFalse(mOverrideSettingsStorage.wasWriteSuccessful());
}
@@ -263,10 +289,10 @@
// Write some settings to storage.
DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
- SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
- overrideSettings.mShouldShowSystemDecors = true;
- overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
- provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+ updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+ overrideSettings.mShouldShowSystemDecors = true;
+ overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
+ });
assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
// Verify that settings were stored correctly.
@@ -283,16 +309,16 @@
final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
final int initialSize = provider.getOverrideSettingsSize();
-
- // Size + 1 when query for a new display.
final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
- final SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
- assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
+ updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+ // Size + 1 when query for a new display.
+ assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
- // When a display is removed, its override Settings is not removed if there is any override.
- overrideSettings.mShouldShowSystemDecors = true;
- provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+ // When a display is removed, its override Settings is not removed if there is any
+ // override.
+ overrideSettings.mShouldShowSystemDecors = true;
+ });
provider.onDisplayRemoved(secondaryDisplayInfo);
assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
@@ -309,23 +335,53 @@
final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
final int initialSize = provider.getOverrideSettingsSize();
-
- // Size + 1 when query for a new display.
final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
secondaryDisplayInfo.type = TYPE_VIRTUAL;
- final SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
- assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
+ updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+ // Size + 1 when query for a new display.
+ assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
- // When a virtual display is removed, its override Settings is removed even if it has
- // override.
- overrideSettings.mShouldShowSystemDecors = true;
- provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+ // When a virtual display is removed, its override Settings is removed
+ // even if it has override.
+ overrideSettings.mShouldShowSystemDecors = true;
+ });
provider.onDisplayRemoved(secondaryDisplayInfo);
assertEquals(initialSize, provider.getOverrideSettingsSize());
}
+ @Test
+ public void testRemovesStaleDisplaySettings() {
+ assumeTrue(com.android.window.flags.Flags.perUserDisplayWindowSettings());
+
+ final DisplayWindowSettingsProvider provider =
+ new DisplayWindowSettingsProvider(mDefaultVendorSettingsStorage,
+ mOverrideSettingsStorage);
+ final DisplayInfo displayInfo = mSecondaryDisplay.getDisplayInfo();
+ updateOverrideSettings(provider, displayInfo, settings -> settings.mForcedDensity = 356);
+ mRootWindowContainer.removeChild(mSecondaryDisplay);
+
+ provider.removeStaleDisplaySettings(mRootWindowContainer);
+
+ assertThat(mOverrideSettingsStorage.wasWriteSuccessful()).isTrue();
+ assertThat(provider.getOverrideSettingsSize()).isEqualTo(0);
+ }
+
+ /**
+ * Updates the override settings for a specific display.
+ *
+ * @param provider the provider to obtain and update the settings from.
+ * @param displayInfo the information about the display to be updated.
+ * @param modifier a function that modifies the settings for the display.
+ */
+ private static void updateOverrideSettings(DisplayWindowSettingsProvider provider,
+ DisplayInfo displayInfo, Consumer<SettingsEntry> modifier) {
+ final SettingsEntry settings = provider.getOverrideSettings(displayInfo);
+ modifier.accept(settings);
+ provider.updateOverrideSettings(displayInfo, settings);
+ }
+
/**
* Prepares display settings and stores in {@link #mOverrideSettingsStorage}. Uses provided
* display identifier and stores windowingMode=WINDOWING_MODE_PINNED.
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index bdd45c6..74e2d44 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -18,10 +18,6 @@
import static android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
@@ -31,9 +27,6 @@
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
@@ -45,7 +38,6 @@
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.spyOn;
-import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -54,8 +46,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -129,200 +119,7 @@
mController = new LetterboxUiController(mWm, mActivity);
}
- // shouldRefreshActivityForCameraCompat
- @Test
- public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
- doReturn(false).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
-
- assertFalse(mController.shouldRefreshActivityForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
- public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
-
- assertFalse(mController.shouldRefreshActivityForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
- public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertFalse(mController.shouldRefreshActivityForCameraCompat());
- }
-
- @Test
- public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ false);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertFalse(mController.shouldRefreshActivityForCameraCompat());
- }
-
- @Test
- public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertTrue(mController.shouldRefreshActivityForCameraCompat());
- }
-
- // shouldRefreshActivityViaPauseForCameraCompat
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
- public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
- doReturn(false).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
-
- assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
- public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
-
- assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
- public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsFalseAndOverride_returnFalse()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ false);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
- }
-
- @Test
- public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ true);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
- }
-
- // shouldForceRotateForCameraCompat
-
- @Test
- public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
- doReturn(false).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
-
- assertFalse(mController.shouldForceRotateForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
- public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
-
- assertFalse(mController.shouldForceRotateForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
- public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertFalse(mController.shouldForceRotateForCameraCompat());
- }
-
- @Test
- public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ false);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertFalse(mController.shouldForceRotateForCameraCompat());
- }
-
- @Test
- public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue()
- throws Exception {
- doReturn(true).when(mLetterboxConfiguration)
- .isCameraCompatTreatmentEnabled();
- mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertTrue(mController.shouldForceRotateForCameraCompat());
- }
-
- // shouldApplyFreeformTreatmentForCameraCompat
-
- @Test
- public void testShouldApplyCameraCompatFreeformTreatment_flagIsDisabled_returnsFalse() {
- mSetFlagsRule.disableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
- assertFalse(mController.shouldApplyFreeformTreatmentForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
- public void testShouldApplyCameraCompatFreeformTreatment_overrideEnabled_returnsFalse() {
- mSetFlagsRule.enableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
- assertFalse(mController.shouldApplyFreeformTreatmentForCameraCompat());
- }
-
- @Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
- public void testShouldApplyCameraCompatFreeformTreatment_disabledByOverride_returnsFalse()
- throws Exception {
- mSetFlagsRule.enableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertFalse(mController.shouldApplyFreeformTreatmentForCameraCompat());
- }
-
- @Test
- public void testShouldApplyCameraCompatFreeformTreatment_notDisabledByOverride_returnsTrue()
- throws Exception {
- mSetFlagsRule.enableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
- mController = new LetterboxUiController(mWm, mActivity);
-
- assertTrue(mController.shouldApplyFreeformTreatmentForCameraCompat());
- }
@Test
public void testGetCropBoundsIfNeeded_handleCropForTransparentActivityBasedOnOpaqueBounds() {
@@ -641,39 +438,6 @@
assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
}
- @Test
- public void testRecomputeConfigurationForCameraCompatIfNeeded() {
- spyOn(mController);
- doReturn(false).when(mController).isOverrideOrientationOnlyForCameraEnabled();
- doReturn(false).when(mController).isCameraCompatSplitScreenAspectRatioAllowed();
- doReturn(false).when(mController).shouldOverrideMinAspectRatioForCamera();
- clearInvocations(mActivity);
-
- mController.recomputeConfigurationForCameraCompatIfNeeded();
-
- verify(mActivity, never()).recomputeConfiguration();
-
- // isOverrideOrientationOnlyForCameraEnabled
- doReturn(true).when(mController).isOverrideOrientationOnlyForCameraEnabled();
- clearInvocations(mActivity);
- mController.recomputeConfigurationForCameraCompatIfNeeded();
- verify(mActivity).recomputeConfiguration();
-
- // isCameraCompatSplitScreenAspectRatioAllowed
- doReturn(false).when(mController).isOverrideOrientationOnlyForCameraEnabled();
- doReturn(true).when(mController).isCameraCompatSplitScreenAspectRatioAllowed();
- clearInvocations(mActivity);
- mController.recomputeConfigurationForCameraCompatIfNeeded();
- verify(mActivity).recomputeConfiguration();
-
- // shouldOverrideMinAspectRatioForCamera
- doReturn(false).when(mController).isCameraCompatSplitScreenAspectRatioAllowed();
- doReturn(true).when(mController).shouldOverrideMinAspectRatioForCamera();
- clearInvocations(mActivity);
- mController.recomputeConfigurationForCameraCompatIfNeeded();
- verify(mActivity).recomputeConfiguration();
- }
-
private void prepareActivityForShouldApplyUserMinAspectRatioOverride(
boolean orientationRequest) {
spyOn(mController);
@@ -875,7 +639,8 @@
doReturn(true).when(mActivity).isCameraActive();
mController = new LetterboxUiController(mWm, mActivity);
- assertTrue(mController.shouldOverrideMinAspectRatioForCamera());
+ assertTrue(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera());
}
@Test
@@ -886,7 +651,8 @@
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
mController = new LetterboxUiController(mWm, mActivity);
- assertTrue(mController.shouldOverrideMinAspectRatioForCamera());
+ assertTrue(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera());
}
@Test
@@ -897,7 +663,8 @@
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+ assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera());
}
@Test
@@ -908,7 +675,8 @@
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+ assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera());
}
@Test
@@ -917,7 +685,8 @@
doReturn(true).when(mActivity).isCameraActive();
mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+ assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera());
}
@Test
@@ -927,7 +696,8 @@
mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+ assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera());
}
@Test
@@ -938,7 +708,8 @@
doReturn(true).when(mActivity).isCameraActive();
mController = new LetterboxUiController(mWm, mActivity);
- assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+ assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldOverrideMinAspectRatioForCamera());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
index c5bf78b..7efbc88 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
@@ -29,7 +29,7 @@
import com.android.internal.protolog.ProtoLogImpl;
import com.android.internal.protolog.common.IProtoLog;
import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
import org.junit.After;
import org.junit.Ignore;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index eb79118..3078df0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -392,6 +392,8 @@
assertEquals(newPipTask, mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask());
assertNotEquals(newPipTask, activity1.getTask());
assertFalse("Created PiP task must not be in recents", newPipTask.inRecents);
+ assertThat(newPipTask.autoRemoveRecents).isTrue();
+ assertThat(activity1.getTask().autoRemoveRecents).isFalse();
}
/**
@@ -427,6 +429,7 @@
bounds.scale(0.5f);
task.setBounds(bounds);
assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertThat(task.autoRemoveRecents).isFalse();
}
/**
@@ -451,6 +454,7 @@
// Ensure a task has moved over.
ensureTaskPlacement(task, activity);
assertTrue(task.inPinnedWindowingMode());
+ assertThat(task.autoRemoveRecents).isFalse();
}
/**
@@ -480,6 +484,8 @@
ensureTaskPlacement(fullscreenTask, secondActivity);
assertTrue(pinnedRootTask.inPinnedWindowingMode());
assertEquals(WINDOWING_MODE_FULLSCREEN, fullscreenTask.getWindowingMode());
+ assertThat(pinnedRootTask.autoRemoveRecents).isTrue();
+ assertThat(secondActivity.getTask().autoRemoveRecents).isFalse();
}
@Test
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 3a85451..64527cb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1315,6 +1315,47 @@
@Test
@EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+ ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL})
+ public void testOverrideMinAspectRatioSmall_overridden() {
+ final int dh = 1200;
+ final int dw = 1000;
+ setUpDisplaySizeWithApp(dw, dh);
+
+ // Create a size compat activity on the same task.
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .build();
+
+ final Rect bounds = activity.getBounds();
+ assertEquals(dh, bounds.height());
+ assertEquals(dh / ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE,
+ bounds.width(), 0.5f);
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+ ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL})
+ public void testOverrideMinAspectRatioSmall_notOverridden() {
+ final int dh = 1200;
+ final int dw = 1000;
+ setUpDisplaySizeWithApp(dw, dh);
+
+ // Create a size compat activity on the same task.
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setMinAspectRatio(OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE)
+ .build();
+
+ // Activity's requested aspect ratio is larger than OVERRIDE_MIN_ASPECT_RATIO_SMALL,
+ // so OVERRIDE_MIN_ASPECT_RATIO_SMALL is ignored.
+ final Rect bounds = activity.getBounds();
+ assertEquals(dh, bounds.height());
+ assertEquals(dh / OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
+ bounds.width(), 0.5f);
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM})
public void testOverrideMinAspectRatioMedium() {
setUpDisplaySizeWithApp(1000, 1200);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index e01cea3..4bc87b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -42,6 +42,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE;
+import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK;
import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
@@ -222,6 +223,27 @@
}
@Test
+ public void testReparentPinnedActivityBackToOriginalTask() {
+ final ActivityRecord activityMain = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ final Task originalTask = activityMain.getTask();
+ final ActivityRecord activityPip = new ActivityBuilder(mAtm).setTask(originalTask).build();
+ activityPip.setState(RESUMED, "test");
+ mAtm.mRootWindowContainer.moveActivityToPinnedRootTask(activityPip,
+ null /* launchIntoPipHostActivity */, "test");
+ final Task pinnedActivityTask = activityPip.getTask();
+
+ // Simulate pinnedActivityTask unintentionally added to recent during top activity resume.
+ mAtm.getRecentTasks().getRawTasks().add(pinnedActivityTask);
+
+ // Reparent the activity back to its original task when exiting PIP mode.
+ pinnedActivityTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+ assertThat(activityPip.getTask()).isEqualTo(originalTask);
+ assertThat(originalTask.autoRemoveRecents).isFalse();
+ assertThat(mAtm.getRecentTasks().getRawTasks()).containsExactly(originalTask);
+ }
+
+ @Test
public void testReparent_BetweenDisplays() {
// Create first task on primary display.
final Task rootTask1 = createTask(mDisplayContent);
@@ -1991,7 +2013,7 @@
public void getTaskInfoPropagatesCameraCompatMode() {
final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = task.getTopMostActivity();
- activity.mLetterboxUiController
+ activity.mAppCompatController.getAppCompatCameraOverrides()
.setFreeformCameraCompatMode(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT);
assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
index 628c65e..f07b402 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
@@ -16,47 +16,22 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-
-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.anyBoolean;
import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import android.app.WindowConfiguration;
-import android.content.res.Configuration;
-import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import androidx.annotation.NonNull;
-import com.android.server.wm.utils.TestComponentStack;
-
-import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
/**
* Test class for {@link TransparentPolicy}.
@@ -71,199 +46,238 @@
@Test
public void testNotStartingWhenDisabled() {
runTestScenario((robot) -> {
- robot.launchTransparentActivityInTask();
+ robot.transparentActivity((ta) -> {
+ ta.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStateIsNotRunning();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+ });
}, /* policyEnabled */ false);
}
@Test
public void testNotStartingWithoutTask() {
runTestScenario((robot) -> {
- robot.launchTransparentActivity();
+ robot.transparentActivity((ta) -> {
+ ta.launchTransparentActivity();
- robot.checkTopActivityPolicyStartNotInvoked();
- robot.checkTopActivityPolicyStateIsNotRunning();
+ ta.checkTopActivityTransparentPolicyStartNotInvoked();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+ });
});
}
@Test
public void testPolicyRunningWhenTransparentIsUsed() {
runTestScenario((robot) -> {
- robot.launchTransparentActivityInTask();
+ robot.transparentActivity((ta) -> {
+ ta.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStartNotInvoked();
- robot.checkTopActivityPolicyStateIsRunning();
+ ta.checkTopActivityTransparentPolicyStartNotInvoked();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+ });
});
}
@Test
public void testCleanLetterboxConfigListenerWhenTranslucentIsDestroyed() {
runTestScenario((robot) -> {
- robot.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStartNotInvoked();
- robot.checkTopActivityPolicyStateIsRunning();
+ robot.transparentActivity((ta) -> {
+ ta.launchTransparentActivityInTask();
+ ta.checkTopActivityTransparentPolicyStartNotInvoked();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
- robot.clearInteractions();
- robot.destroyTopActivity();
+ robot.clearInteractions();
+ ta.activity().destroyTopActivity();
- robot.checkTopActivityPolicyStopInvoked();
- robot.checkTopActivityPolicyStateIsNotRunning();
+ ta.checkTopActivityTransparentPolicyStopInvoked();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+ });
});
}
@Test
public void testApplyStrategyAgainWhenOpaqueIsDestroyed() {
runTestScenario((robot) -> {
- robot.launchOpaqueActivityInTask();
- robot.checkTopActivityPolicyStateIsNotRunning();
+ robot.transparentActivity((ta) -> {
+ ta.launchOpaqueActivityInTask();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
- robot.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStateIsRunning();
+ ta.launchTransparentActivityInTask();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
- robot.destroyActivity(/* fromTop */ 1);
- robot.checkTopActivityPolicyStartInvoked();
+ ta.activity().destroyActivity(/* fromTop */ 1);
+ ta.checkTopActivityTransparentPolicyStartInvoked();
+ });
});
}
@Test
public void testResetOpaqueReferenceWhenOpaqueIsDestroyed() {
runTestScenario((robot) -> {
- robot.launchTransparentActivityInTask();
+ robot.transparentActivity((ta) -> {
+ ta.launchTransparentActivityInTask();
- robot.clearInteractions();
- robot.destroyActivity(/* fromTop */ 1);
+ robot.clearInteractions();
+ ta.activity().destroyActivity(/* fromTop */ 1);
- robot.checkTopActivityPolicyStartInvoked();
- robot.checkTopActivityPolicyStateIsNotRunning();
+ ta.checkTopActivityTransparentPolicyStartInvoked();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+ });
});
}
@Test
public void testNotApplyStrategyAgainWhenOpaqueIsNotDestroyed() {
runTestScenario((robot) -> {
- robot.launchOpaqueActivityInTask();
- robot.checkTopActivityPolicyStateIsNotRunning();
+ robot.transparentActivity((ta) -> {
+ ta.launchOpaqueActivityInTask();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
- robot.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStateIsRunning();
+ ta.launchTransparentActivityInTask();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
- robot.clearInteractions();
- robot.checkTopActivityPolicyStopNotInvoked();
+ robot.clearInteractions();
+ ta.checkTopActivityTransparentPolicyStopNotInvoked();
+ });
});
}
@Test
public void testApplyStrategyToTranslucentActivities() {
runTestScenario((robot) -> {
- robot.configureTopActivity(/* minAspect */ 1.2f, /* maxAspect */ 1.5f,
- SCREEN_ORIENTATION_PORTRAIT, /* isUnresizable */ true);
- robot.configureTopActivityIgnoreOrientationRequest(true);
- robot.launchActivity(/* minAspect */ 1.1f, /* maxAspect */ 3f,
- SCREEN_ORIENTATION_LANDSCAPE, /* transparent */true, /* addToTask */true);
- robot.checkTopActivityPolicyStateIsRunning();
- robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
- robot.checkTopOrientation(SCREEN_ORIENTATION_PORTRAIT);
- robot.checkTopAspectRatios(/* minAspectRatio */ 1.2f, /* maxAspectRatio */ 1.5f);
+ robot.transparentActivity((ta) -> {
+ ta.applyOnActivity((a) -> {
+ a.configureTopActivity(/* minAspect */ 1.2f, /* maxAspect */ 1.5f,
+ SCREEN_ORIENTATION_PORTRAIT, /* isUnresizable */ true);
+ a.configureTopActivityIgnoreOrientationRequest(true);
+ a.launchActivity(/* minAspect */ 1.1f, /* maxAspect */ 3f,
+ SCREEN_ORIENTATION_LANDSCAPE, /* transparent */true,
+ /* withComponent */ false, /* addToTask */true);
+ });
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+ ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+ ta.applyOnActivity((a) -> {
+ a.checkTopActivityConfigOrientation(SCREEN_ORIENTATION_PORTRAIT);
+ a.checkTopActivityAspectRatios(/* minAspectRatio */ 1.2f,
+ /* maxAspectRatio */ 1.5f);
+ });
+ });
});
}
@Test
public void testApplyStrategyToTransparentActivitiesRetainsWindowConfigurationProperties() {
runTestScenario((robot) -> {
- robot.launchTransparentActivity();
+ robot.transparentActivity((ta) -> {
+ ta.launchTransparentActivity();
- robot.forceChangeInTopActivityConfiguration();
- robot.attachTopActivityToTask();
+ ta.forceChangeInTopActivityConfiguration();
+ ta.activity().attachTopActivityToTask();
- robot.checkTopActivityConfigurationConfiguration();
+ ta.checkTopActivityConfigurationConfiguration();
+ });
});
}
@Test
public void testApplyStrategyToMultipleTranslucentActivities() {
runTestScenario((robot) -> {
- robot.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStateIsRunning();
- robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+ robot.transparentActivity((ta) -> {
+ ta.launchTransparentActivityInTask();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+ ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
- robot.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStateIsRunning();
- robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 2);
+ ta.launchTransparentActivityInTask();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+ ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 2);
+ });
});
}
@Test
public void testNotApplyStrategyToTranslucentActivitiesOverEmbeddedActivities() {
runTestScenario((robot) -> {
- robot.configureTopActivityAsEmbedded();
- robot.launchTransparentActivityInTask();
+ robot.transparentActivity((ta) -> {
+ ta.activity().setTopActivityAsEmbedded(true);
+ ta.launchTransparentActivityInTask();
- robot.checkTopActivityPolicyStartNotInvoked();
- robot.checkTopActivityPolicyStateIsNotRunning();
+ ta.checkTopActivityTransparentPolicyStartNotInvoked();
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+ });
});
}
@Test
public void testTranslucentActivitiesDontGoInSizeCompatMode() {
runTestScenario((robot) -> {
- robot.configureTopActivityIgnoreOrientationRequest(true);
- robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
- robot.rotateDisplayForTopActivity(ROTATION_90);
- robot.checkTopActivitySizeCompatMode(/* inScm */ true);
- robot.rotateDisplayForTopActivity(ROTATION_0);
- robot.checkTopActivitySizeCompatMode(/* inScm */ false);
+ robot.transparentActivity((ta) -> {
+ ta.applyOnActivity((a) -> {
+ a.configureTopActivityIgnoreOrientationRequest(true);
+ a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+ a.rotateDisplayForTopActivity(ROTATION_90);
+ a.checkTopActivityInSizeCompatMode(/* inScm */ true);
+ a.rotateDisplayForTopActivity(ROTATION_0);
+ a.checkTopActivityInSizeCompatMode(/* inScm */ false);
- robot.launchTransparentActivityInTask();
- robot.checkTopActivitySizeCompatMode(/* inScm */ false);
- robot.rotateDisplayForTopActivity(ROTATION_90);
- robot.checkTopActivitySizeCompatMode(/* inScm */ false);
+ ta.launchTransparentActivityInTask();
+
+ a.checkTopActivityInSizeCompatMode(/* inScm */ false);
+ a.rotateDisplayForTopActivity(ROTATION_90);
+ a.checkTopActivityInSizeCompatMode(/* inScm */ false);
+ });
+ });
}, /* displayWidth */ 2800, /* displayHeight */ 1400);
}
@Test
public void testCheckOpaqueIsLetterboxedWhenStrategyIsApplied() {
runTestScenario((robot) -> {
- robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
- robot.configureTopActivityIgnoreOrientationRequest(true);
- robot.launchTransparentActivity();
+ robot.transparentActivity((ta) -> {
+ ta.applyOnActivity((a) -> {
+ a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+ a.configureTopActivityIgnoreOrientationRequest(true);
+ ta.launchTransparentActivity();
- robot.assertFalseOnTopActivity(ActivityRecord::fillsParent);
- robot.assertTrueOnActivity(/* fromTop */ 1, ActivityRecord::fillsParent);
- robot.applyTo(/* fromTop */ 1, (activity) -> {
- activity.finishing = true;
+ a.assertFalseOnTopActivity(ActivityRecord::fillsParent);
+ a.assertTrueOnActivity(/* fromTop */ 1, ActivityRecord::fillsParent);
+ a.applyToActivity(/* fromTop */ 1, (activity) -> {
+ activity.finishing = true;
+ });
+ a.assertFalseOnActivity(/* fromTop */ 1, ActivityRecord::occludesParent);
+ a.attachTopActivityToTask();
+
+ ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+ });
});
- robot.assertFalseOnActivity(/* fromTop */ 1, ActivityRecord::occludesParent);
- robot.attachTopActivityToTask();
-
- robot.checkTopActivityPolicyStateIsNotRunning();
});
}
@Test
public void testTranslucentActivitiesWhenUnfolding() {
runTestScenario((robot) -> {
- robot.applyToTop((activity) -> {
- activity.mWmService.mLetterboxConfiguration
- .setLetterboxHorizontalPositionMultiplier(1.0f);
+ robot.transparentActivity((ta) -> {
+ ta.applyOnActivity((a) -> {
+ a.applyToTopActivity((topActivity) -> {
+ topActivity.mWmService.mLetterboxConfiguration
+ .setLetterboxHorizontalPositionMultiplier(1.0f);
+ });
+ a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+ a.configureTopActivityIgnoreOrientationRequest(true);
+ ta.launchTransparentActivityInTask();
+ ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+
+ a.setTaskWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ a.configureTopActivityFoldablePosture(/* isHalfFolded */ true,
+ /* isTabletop */ false);
+ a.checkTopActivityRecomputedConfiguration();
+ ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+ robot.clearInteractions();
+ a.configureTopActivityFoldablePosture(/* isHalfFolded */ false,
+ /* isTabletop */ false);
+ a.checkTopActivityRecomputedConfiguration();
+ ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+ });
});
- robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
- robot.configureTopActivityIgnoreOrientationRequest(true);
- robot.launchTransparentActivityInTask();
- robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
-
- robot.configureTaskWindowingMode(WINDOWING_MODE_FULLSCREEN);
-
- robot.configureTopActivityFoldablePosture(/* isHalfFolded */ true,
- /* isTabletop */ false);
- robot.checkTopActivityRecomputedConfiguration();
- robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
- robot.clearInteractions();
-
- robot.configureTopActivityFoldablePosture(/* isHalfFolded */ false,
- /* isTabletop */ false);
- robot.checkTopActivityRecomputedConfiguration();
- robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
}, /* displayWidth */ 2800, /* displayHeight */ 1400);
}
@@ -271,31 +285,28 @@
@Test
public void testTranslucentActivity_clearSizeCompatMode_inheritedCompatDisplayInsetsCleared() {
runTestScenario((robot) -> {
- robot.configureTopActivityIgnoreOrientationRequest(true);
- robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
- // Rotate to put activity in size compat mode.
- robot.rotateDisplayForTopActivity(ROTATION_90);
- robot.checkTopActivitySizeCompatMode(/* inScm */ true);
+ robot.transparentActivity((ta) -> {
+ ta.applyOnActivity((a) -> {
+ a.configureTopActivityIgnoreOrientationRequest(true);
+ a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+ // Rotate to put activity in size compat mode.
+ a.rotateDisplayForTopActivity(ROTATION_90);
+ a.checkTopActivityInSizeCompatMode(/* inScm */ true);
- robot.launchTransparentActivityInTask();
- robot.assertNotNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
- robot.applyToTop(ActivityRecord::clearSizeCompatMode);
- robot.assertNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
+ ta.launchTransparentActivityInTask();
+ a.assertNotNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
+ a.applyToTopActivity(ActivityRecord::clearSizeCompatMode);
+ a.assertNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
+ });
+ });
});
}
private void runTestScenario(Consumer<TransparentPolicyRobotTest> consumer,
boolean policyEnabled, int displayWidth, int displayHeight) {
- spyOn(mWm.mLetterboxConfiguration);
- when(mWm.mLetterboxConfiguration.isTranslucentLetterboxingEnabled())
- .thenReturn(policyEnabled);
- final TestDisplayContent.Builder builder = new TestDisplayContent.Builder(mAtm,
- displayWidth, displayHeight);
- final Task task = new TaskBuilder(mSupervisor).setDisplay(builder.build())
- .setCreateActivity(true).build();
- final ActivityRecord opaqueActivity = task.getTopNonFinishingActivity();
- final TransparentPolicyRobotTest robot = new TransparentPolicyRobotTest(mAtm, task,
- opaqueActivity);
+ final TransparentPolicyRobotTest robot =
+ new TransparentPolicyRobotTest(mWm, mAtm, mSupervisor, displayWidth, displayHeight);
+ robot.conf().enableTranslucentPolicy(policyEnabled);
consumer.accept(robot);
}
@@ -316,289 +327,31 @@
/**
* Robot pattern implementation for TransparentPolicy
- * TODO(b/344587983): Extract Robot to be reused in different test classes.
*/
- private static class TransparentPolicyRobotTest {
+ private static class TransparentPolicyRobotTest extends AppCompatRobotBase {
@NonNull
- private final ActivityTaskManagerService mAtm;
- @NonNull
- private final Task mTask;
- @NonNull
- private final TestComponentStack<ActivityRecord> mActivityStack;
- @NonNull
- private WindowConfiguration mTopActivityWindowConfiguration;
+ private final AppCompatTransparentActivityRobot mTransparentActivityRobot;
- private TransparentPolicyRobotTest(@NonNull ActivityTaskManagerService atm,
- @NonNull Task task,
- @NonNull ActivityRecord opaqueActivity) {
- mAtm = atm;
- mTask = task;
- mActivityStack = new TestComponentStack<>();
- mActivityStack.push(opaqueActivity);
- spyOn(opaqueActivity.mAppCompatController.getTransparentPolicy());
+ private TransparentPolicyRobotTest(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm,
+ @NonNull ActivityTaskSupervisor supervisor,
+ int displayWidth, int displayHeight) {
+ super(wm, atm, supervisor, displayWidth, displayHeight);
+ mTransparentActivityRobot = new AppCompatTransparentActivityRobot(activity());
+ // We always create at least an opaque activity in a Task
+ activity().createNewTaskWithBaseActivity();
}
- void configureTopActivityAsEmbedded() {
- final ActivityRecord topActivity = mActivityStack.top();
- spyOn(topActivity);
- doReturn(true).when(topActivity).isEmbedded();
- }
-
- private void launchActivity(float minAspectRatio, float maxAspectRatio,
- @Configuration.Orientation int orientation, boolean transparent,
- boolean addToTask) {
- final ActivityBuilder activityBuilder = new ActivityBuilder(mAtm)
- .setScreenOrientation(orientation)
- .setLaunchedFromUid(mActivityStack.base().getUid());
- if (transparent) {
- activityBuilder.setActivityTheme(android.R.style.Theme_Translucent);
- }
- if (minAspectRatio >= 0) {
- activityBuilder.setMinAspectRatio(minAspectRatio);
- }
- if (maxAspectRatio >= 0) {
- activityBuilder.setMaxAspectRatio(maxAspectRatio);
- }
- final ActivityRecord newActivity = activityBuilder.build();
- if (addToTask) {
- mTask.addChild(newActivity);
- }
- spyOn(newActivity.mAppCompatController.getTransparentPolicy());
- mActivityStack.push(newActivity);
- }
-
- void attachTopActivityToTask() {
- mTask.addChild(mActivityStack.top());
- }
-
- void launchTransparentActivity() {
- launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
- SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
- /* addToTask */ false);
- }
-
- void launchTransparentActivityInTask() {
- launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
- SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
- /* addToTask */true);
- }
-
- void launchOpaqueActivityInTask() {
- launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
- SCREEN_ORIENTATION_PORTRAIT, /* transparent */ false,
- /* addToTask */true);
- }
-
- void destroyTopActivity() {
- mActivityStack.top().removeImmediately();
- }
-
- void destroyActivity(int fromTop) {
- mActivityStack.applyTo(/* fromTop */ fromTop, ActivityRecord::removeImmediately);
- }
-
- void forceChangeInTopActivityConfiguration() {
- mActivityStack.applyToTop((activity) -> {
- final Configuration requestedConfig = activity.getRequestedOverrideConfiguration();
- mTopActivityWindowConfiguration = requestedConfig.windowConfiguration;
- mTopActivityWindowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
- mTopActivityWindowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- mTopActivityWindowConfiguration.setAlwaysOnTop(true);
- activity.onRequestedOverrideConfigurationChanged(requestedConfig);
- });
- }
-
- void checkTopActivityPolicyStateIsRunning() {
- assertTrue(mActivityStack.top().mAppCompatController
- .getTransparentPolicy().isRunning());
- }
-
- void checkTopActivityPolicyStateIsNotRunning() {
- assertFalse(mActivityStack.top().mAppCompatController
- .getTransparentPolicy().isRunning());
- }
-
- void checkTopActivityPolicyStopInvoked() {
- verify(mActivityStack.top().mAppCompatController.getTransparentPolicy()).stop();
- }
-
- void checkTopActivityPolicyStopNotInvoked() {
- mActivityStack.applyToTop((activity) -> {
- verify(activity.mAppCompatController.getTransparentPolicy(), never()).stop();
- });
- }
-
- void checkTopActivityPolicyStartInvoked() {
- mActivityStack.applyToTop((activity) -> {
- verify(activity.mAppCompatController.getTransparentPolicy()).start();
- });
- }
-
- void checkTopActivityPolicyStartNotInvoked() {
- verify(mActivityStack.top().mAppCompatController.getTransparentPolicy(),
- never()).start();
- }
-
- void assertTrueOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
- mActivityStack.applyTo(fromTop, (activity) -> {
- Assert.assertTrue(predicate.test(activity));
- });
- }
-
- void assertFalseOnTopActivity(Predicate<ActivityRecord> predicate) {
- Assert.assertFalse(predicate.test(mActivityStack.top()));
- }
-
- void assertFalseOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
- mActivityStack.applyTo(fromTop, (activity) -> {
- Assert.assertFalse(predicate.test(activity));
- });
- }
-
- void assertNotNullOnTopActivity(Function<ActivityRecord, Object> getter) {
- Assert.assertNotNull(getter.apply(mActivityStack.top()));
- }
-
- void assertNullOnTopActivity(Function<ActivityRecord, Object> getter) {
- Assert.assertNull(getter.apply(mActivityStack.top()));
- }
-
- void checkTopActivityConfigurationConfiguration() {
- mActivityStack.applyToTop((activity) -> {
- // The original override of WindowConfiguration should keep.
- assertEquals(ACTIVITY_TYPE_STANDARD, activity.getActivityType());
- assertEquals(WINDOWING_MODE_MULTI_WINDOW,
- mTopActivityWindowConfiguration.getWindowingMode());
- assertTrue(mTopActivityWindowConfiguration.isAlwaysOnTop());
- // Unless display is going to be rotated, it should always inherit from parent.
- assertEquals(ROTATION_UNDEFINED,
- mTopActivityWindowConfiguration.getDisplayRotation());
- });
- }
-
- void checkTopActivityHasInheritedBoundsFrom(int fromTop) {
- final ActivityRecord topActivity = mActivityStack.top();
- final ActivityRecord otherActivity = mActivityStack.getFromTop(/* fromTop */ fromTop);
- final Rect opaqueBounds = otherActivity.getConfiguration().windowConfiguration
- .getBounds();
- final Rect translucentRequestedBounds = topActivity.getRequestedOverrideBounds();
- Assert.assertEquals(opaqueBounds, translucentRequestedBounds);
- }
-
- void checkTopActivityRecomputedConfiguration() {
- verify(mActivityStack.top()).recomputeConfiguration();
- }
-
- void checkTopOrientation(int orientation) {
- Assert.assertEquals(orientation, mActivityStack.top()
- .getRequestedConfigurationOrientation());
- }
-
- void configureTaskWindowingMode(int windowingMode) {
- mTask.setWindowingMode(windowingMode);
- }
-
- void checkTopAspectRatios(float minAspectRatio, float maxAspectRatio) {
- final ActivityRecord topActivity = mActivityStack.top();
- Assert.assertEquals(minAspectRatio, topActivity.getMinAspectRatio(), 0.0001);
- Assert.assertEquals(maxAspectRatio, topActivity.getMaxAspectRatio(), 0.0001);
- }
-
- void checkTopActivitySizeCompatMode(boolean inScm) {
- Assert.assertEquals(inScm, mActivityStack.top().inSizeCompatMode());
+ void transparentActivity(@NonNull Consumer<AppCompatTransparentActivityRobot> consumer) {
+ consumer.accept(mTransparentActivityRobot);
}
void clearInteractions() {
- mActivityStack.applyToAll((activity) -> {
+ activity().applyToAllActivities((activity) -> {
clearInvocations(activity);
clearInvocations(activity.mAppCompatController.getTransparentPolicy());
});
}
-
- void configureTopActivity(float minAspect, float maxAspect, int screenOrientation,
- boolean isUnresizable) {
- prepareLimitedBounds(mActivityStack.top(), minAspect, maxAspect, screenOrientation,
- isUnresizable);
- }
-
- void configureTopActivityIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
- mActivityStack.top().mDisplayContent
- .setIgnoreOrientationRequest(ignoreOrientationRequest);
- }
-
- void configureUnresizableTopActivity(int screenOrientation) {
- configureTopActivity(-1, -1, screenOrientation, true);
- }
-
- void applyToTop(Consumer<ActivityRecord> consumer) {
- consumer.accept(mActivityStack.top());
- }
-
- void applyTo(int fromTop, Consumer<ActivityRecord> consumer) {
- mActivityStack.applyTo(fromTop, consumer);
- }
-
- void rotateDisplayForTopActivity(int rotation) {
- rotateDisplay(mActivityStack.top().mDisplayContent, rotation);
- }
-
- /**
- * Setups activity with restriction on its bounds, such as maxAspect, minAspect,
- * fixed orientation, and/or whether it is resizable.
- */
- void prepareLimitedBounds(ActivityRecord activity, float minAspect, float maxAspect,
- int screenOrientation, boolean isUnresizable) {
- activity.info.resizeMode = isUnresizable
- ? RESIZE_MODE_UNRESIZEABLE
- : RESIZE_MODE_RESIZEABLE;
- final Task task = activity.getTask();
- if (task != null) {
- // Update the Task resize value as activity will follow the task.
- task.mResizeMode = activity.info.resizeMode;
- task.getRootActivity().info.resizeMode = activity.info.resizeMode;
- }
- activity.setVisibleRequested(true);
- if (maxAspect >= 0) {
- activity.info.setMaxAspectRatio(maxAspect);
- }
- if (minAspect >= 0) {
- activity.info.setMinAspectRatio(minAspect);
- }
- if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
- activity.info.screenOrientation = screenOrientation;
- activity.setRequestedOrientation(screenOrientation);
- }
- // Make sure to use the provided configuration to construct the size compat fields.
- activity.clearSizeCompatMode();
- activity.ensureActivityConfiguration();
- // Make sure the display configuration reflects the change of activity.
- if (activity.mDisplayContent.updateOrientation()) {
- activity.mDisplayContent.sendNewConfiguration();
- }
- }
-
- void configureTopActivityFoldablePosture(boolean isHalfFolded, boolean isTabletop) {
- mActivityStack.applyToTop((activity) -> {
- final DisplayRotation r = activity.mDisplayContent.getDisplayRotation();
- doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge();
- doReturn(false).when(r)
- .isDeviceInPosture(any(DeviceStateController.DeviceState.class),
- anyBoolean());
- if (isHalfFolded) {
- doReturn(true).when(r)
- .isDeviceInPosture(DeviceStateController.DeviceState.HALF_FOLDED,
- isTabletop);
- }
- activity.recomputeConfiguration();
- });
- }
-
- private static void rotateDisplay(DisplayContent display, int rotation) {
- final Configuration c = new Configuration();
- display.getDisplayRotation().setRotation(rotation);
- display.computeScreenConfiguration(c);
- display.onRequestedOverrideConfigurationChanged(c);
- }
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/CurrentTimeMillisSupplierFake.java b/services/tests/wmtests/src/com/android/server/wm/utils/CurrentTimeMillisSupplierFake.java
new file mode 100644
index 0000000..f4b2adb
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/CurrentTimeMillisSupplierFake.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.utils;
+
+import java.util.function.LongSupplier;
+
+/**
+ * Fake {@link LongSupplier} implementation used in tests.
+ */
+public class CurrentTimeMillisSupplierFake implements LongSupplier {
+
+ private long mCurrenTimeMillis = System.currentTimeMillis();
+
+ /**
+ * @return The currentTimeMilles used in test
+ */
+ @Override
+ public long getAsLong() {
+ return mCurrenTimeMillis;
+ }
+
+ /**
+ * Simulate some time passed.
+ * @param delayInMillis The delay in milliseconds,
+ */
+ public void delay(long delayInMillis) {
+ mCurrenTimeMillis += delayInMillis;
+ }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 27c383c..bf46154 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -113,6 +113,7 @@
import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import com.android.server.utils.AlarmQueue;
@@ -1063,6 +1064,18 @@
synchronized (mReportedEvents) {
LinkedList<Event> events = mReportedEvents.get(userId);
if (events == null) {
+ // TODO (b/347644400): callers of this API should verify that the userId passed to
+ // this method exists - there is currently a known case where USER_ALL is passed
+ // here and it would be added to the queue, never to be flushed correctly. The logic
+ // below should only remain as a last-resort catch-all fix.
+ final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+ if (umi == null || (umi != null && !umi.exists(userId))) {
+ // The userId passed is a non-existent user so don't report the event.
+ Slog.wtf(TAG, "Attempted to report event for non-existent user " + userId
+ + " (" + event.mPackage + "/" + event.mClass
+ + " eventType:" + event.mEventType + ")");
+ return;
+ }
events = new LinkedList<>();
mReportedEvents.put(userId, events);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index cfcc04b..89b9850 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -1165,7 +1165,7 @@
LocalServices.getService(PermissionManagerServiceInternal.class)
.setHotwordDetectionServiceProvider(() -> uid);
mIdentity = new HotwordDetectionServiceIdentity(uid, mVoiceInteractionServiceUid);
- addServiceUidForAudioPolicy(uid);
+ addServiceUidForAudioPolicy(uid, mVoiceInteractionServiceUid);
}
}));
}
@@ -1187,23 +1187,17 @@
});
}
- private void addServiceUidForAudioPolicy(int uid) {
- mScheduledExecutorService.execute(() -> {
- AudioManagerInternal audioManager =
- LocalServices.getService(AudioManagerInternal.class);
- if (audioManager != null) {
- audioManager.addAssistantServiceUid(uid);
- }
- });
+ private void addServiceUidForAudioPolicy(int isolatedUid, int owningUid) {
+ AudioManagerInternal audioManager = LocalServices.getService(AudioManagerInternal.class);
+ if (audioManager != null) {
+ audioManager.addAssistantServiceUid(isolatedUid, owningUid);
+ }
}
private void removeServiceUidForAudioPolicy(int uid) {
- mScheduledExecutorService.execute(() -> {
- AudioManagerInternal audioManager =
- LocalServices.getService(AudioManagerInternal.class);
- if (audioManager != null) {
- audioManager.removeAssistantServiceUid(uid);
- }
- });
+ AudioManagerInternal audioManager = LocalServices.getService(AudioManagerInternal.class);
+ if (audioManager != null) {
+ audioManager.removeAssistantServiceUid(uid);
+ }
}
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 09cb464..61698db 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9981,6 +9981,18 @@
"carrier_roaming_satellite_default_services_int_array";
/**
+ * Indicate whether carrier roaming to satellite is using ESOS (Emergency SOS) which connects
+ * to an emergency provider instead of PSAP (Public Safety Answering Point) for emergency
+ * messaging.
+ *
+ * This will need agreement with carriers before enabling this flag.
+ *
+ * The default value is false.
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public static final String KEY_SATELLITE_ESOS_SUPPORTED_BOOL = "satellite_esos_supported_bool";
+
+ /**
* Indicating whether DUN APN should be disabled when the device is roaming. In that case,
* the default APN (i.e. internet) will be used for tethering.
*
@@ -11137,6 +11149,7 @@
sDefaults.putBoolean(KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, false);
sDefaults.putInt(KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT,
(int) TimeUnit.SECONDS.toMillis(30));
+ sDefaults.putBoolean(KEY_SATELLITE_ESOS_SUPPORTED_BOOL, false);
sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, "");
sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL, false);
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 58488d1..1089602 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -274,6 +274,11 @@
private final int mServiceCapabilities;
/**
+ * Whether the carrier roaming to satellite is using ESOS for emergency messaging.
+ */
+ private final boolean mIsSatelliteESOSSupported;
+
+ /**
* @hide
*
* @deprecated Use {@link SubscriptionInfo.Builder}.
@@ -400,6 +405,7 @@
this.mIsOnlyNonTerrestrialNetwork = false;
this.mServiceCapabilities = 0;
this.mTransferStatus = 0;
+ this.mIsSatelliteESOSSupported = false;
}
/**
@@ -441,6 +447,7 @@
this.mIsOnlyNonTerrestrialNetwork = builder.mIsOnlyNonTerrestrialNetwork;
this.mServiceCapabilities = builder.mServiceCapabilities;
this.mTransferStatus = builder.mTransferStatus;
+ this.mIsSatelliteESOSSupported = builder.mIsSatelliteESOSSupported;
}
/**
@@ -898,6 +905,19 @@
return mIsOnlyNonTerrestrialNetwork;
}
+
+ /**
+ * Checks if the subscription is supported ESOS over Carrier Roaming NB-IOT Satellite.
+ *
+ * @return {@code true} if the subscription supports ESOS over Carrier Roaming NB-IOT Satellite,
+ * {@code false} otherwise.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public boolean isSatelliteESOSSupported() {
+ return mIsSatelliteESOSSupported;
+ }
+
// TODO(b/316183370): replace @code with @link in javadoc after feature is released
/**
* Retrieves the service capabilities for the current subscription.
@@ -989,6 +1009,7 @@
.setServiceCapabilities(
SubscriptionManager.getServiceCapabilitiesSet(source.readInt()))
.setTransferStatus(source.readInt())
+ .setSatelliteESOSSupported(source.readBoolean())
.build();
}
@@ -1033,6 +1054,7 @@
dest.writeBoolean(mIsOnlyNonTerrestrialNetwork);
dest.writeInt(mServiceCapabilities);
dest.writeInt(mTransferStatus);
+ dest.writeBoolean(mIsSatelliteESOSSupported);
}
@Override
@@ -1099,6 +1121,7 @@
+ " serviceCapabilities=" + SubscriptionManager.getServiceCapabilitiesSet(
mServiceCapabilities).toString()
+ " transferStatus=" + mTransferStatus
+ + " isSatelliteESOSSupported=" + mIsSatelliteESOSSupported
+ "]";
}
@@ -1126,7 +1149,8 @@
&& mCountryIso.equals(that.mCountryIso) && mGroupOwner.equals(that.mGroupOwner)
&& mIsOnlyNonTerrestrialNetwork == that.mIsOnlyNonTerrestrialNetwork
&& mServiceCapabilities == that.mServiceCapabilities
- && mTransferStatus == that.mTransferStatus;
+ && mTransferStatus == that.mTransferStatus
+ && mIsSatelliteESOSSupported == that.mIsSatelliteESOSSupported;
}
@Override
@@ -1136,7 +1160,7 @@
mCardString, mIsOpportunistic, mGroupUuid, mCountryIso, mCarrierId, mProfileClass,
mType, mGroupOwner, mAreUiccApplicationsEnabled, mPortIndex, mUsageSetting, mCardId,
mIsGroupDisabled, mIsOnlyNonTerrestrialNetwork, mServiceCapabilities,
- mTransferStatus);
+ mTransferStatus, mIsSatelliteESOSSupported);
result = 31 * result + Arrays.hashCode(mEhplmns);
result = 31 * result + Arrays.hashCode(mHplmns);
result = 31 * result + Arrays.hashCode(mNativeAccessRules);
@@ -1346,6 +1370,11 @@
* Service capabilities bitmasks the subscription supports.
*/
private int mServiceCapabilities = 0;
+ /**
+ * {@code true} if the subscription supports ESOS over Carrier Roaming NB-IOT Satellite.
+ * {@code false} otherwise.
+ */
+ private boolean mIsSatelliteESOSSupported = false;
/**
* Default constructor.
@@ -1392,6 +1421,7 @@
mIsOnlyNonTerrestrialNetwork = info.mIsOnlyNonTerrestrialNetwork;
mServiceCapabilities = info.mServiceCapabilities;
mTransferStatus = info.mTransferStatus;
+ mIsSatelliteESOSSupported = info.mIsSatelliteESOSSupported;
}
/**
@@ -1828,6 +1858,21 @@
}
/**
+ * Set whether the subscription is supported ESOS over Carrier Roaming NB-IOT Satellite or
+ * not.
+ *
+ * @param isSatelliteESOSSupported {@code true} if the subscription supports ESOS over
+ * Carrier Roaming NB-IOT Satellite, {@code false} otherwise.
+ * @return The builder.
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ @NonNull
+ public Builder setSatelliteESOSSupported(boolean isSatelliteESOSSupported) {
+ mIsSatelliteESOSSupported = isSatelliteESOSSupported;
+ return this;
+ }
+
+ /**
* Build the {@link SubscriptionInfo}.
*
* @return The {@link SubscriptionInfo} instance.
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 76b4e005..dea10b70 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1127,7 +1127,7 @@
* <P>Type: INTEGER (int)</P>
* @hide
*/
- public static final String IS_NTN = SimInfo.COLUMN_IS_NTN;
+ public static final String IS_ONLY_NTN = SimInfo.COLUMN_IS_ONLY_NTN;
/**
* TelephonyProvider column name to identify service capabilities.
@@ -1167,6 +1167,16 @@
public static final String SATELLITE_ENTITLEMENT_PLMNS =
SimInfo.COLUMN_SATELLITE_ENTITLEMENT_PLMNS;
+ /**
+ * TelephonyProvider column name to indicate the satellite ESOS supported. The value of this
+ * column is set based on {@link CarrierConfigManager#KEY_SATELLITE_ESOS_SUPPORTED_BOOL}.
+ * By default, it's disabled.
+ * <P>Type: INTEGER (int)</P>
+ *
+ * @hide
+ */
+ public static final String SATELLITE_ESOS_SUPPORTED = SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"USAGE_SETTING_"},
@@ -2783,17 +2793,17 @@
return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
}
- /** @hide */
+ /**
+ * Puts phone ID and subscription ID into the {@code intent}.
+ *
+ * <p>If the subscription ID is not valid, only puts phone ID into the {@code intent}.
+ *
+ * @hide
+ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
int subId = SubscriptionManager.getSubscriptionId(phoneId);
- if (isValidSubscriptionId(subId)) {
- putPhoneIdAndSubIdExtra(intent, phoneId, subId);
- } else {
- logd("putPhoneIdAndSubIdExtra: no valid subs");
- intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
- intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
- }
+ putPhoneIdAndMaybeSubIdExtra(intent, phoneId, subId);
}
/** @hide */
@@ -2806,6 +2816,23 @@
}
/**
+ * Puts phone ID and subscription ID into the {@code intent}.
+ *
+ * <p>If the subscription ID is not valid, only puts phone ID into the {@code intent}.
+ *
+ * @hide
+ */
+ public static void putPhoneIdAndMaybeSubIdExtra(Intent intent, int phoneId, int subId) {
+ if (isValidSubscriptionId(subId)) {
+ putPhoneIdAndSubIdExtra(intent, phoneId, subId);
+ } else {
+ if (VDBG) logd("putPhoneIdAndMaybeSubIdExtra: invalid subId");
+ intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
+ intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
+ }
+ }
+
+ /**
* Get visible subscription Id(s) of the currently active SIM(s).
*
* @return the list of subId's that are active,
diff --git a/telephony/java/android/telephony/satellite/ProvisionSubscriberId.aidl b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.aidl
new file mode 100644
index 0000000..fe46db8
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2024, 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 android.telephony.satellite;
+
+parcelable ProvisionSubscriberId;
diff --git a/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java
new file mode 100644
index 0000000..796c82d
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2024 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 android.telephony.satellite;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.telephony.flags.Flags;
+
+import java.util.Objects;
+
+/**
+ * ProvisionSubscriberId
+ *
+ * Satellite Gateway client will use these subscriber ids to register with satellite gateway service
+ * which identify user subscription with unique subscriber ids. These subscriber ids can be any
+ * unique value like iccid, imsi or msisdn which is decided based upon carrier requirements.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+public final class ProvisionSubscriberId implements Parcelable {
+ /** provision subscriberId */
+ @NonNull
+ private String mSubscriberId;
+
+ /** carrier id */
+ private int mCarrierId;
+
+ /**
+ * @hide
+ */
+ public ProvisionSubscriberId(@NonNull String subscriberId, @NonNull int carrierId) {
+ this.mCarrierId = carrierId;
+ this.mSubscriberId = subscriberId;
+ }
+
+ private ProvisionSubscriberId(Parcel in) {
+ readFromParcel(in);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeString(mSubscriberId);
+ out.writeInt(mCarrierId);
+ }
+
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public static final @android.annotation.NonNull Creator<ProvisionSubscriberId> CREATOR =
+ new Creator<ProvisionSubscriberId>() {
+ @Override
+ public ProvisionSubscriberId createFromParcel(Parcel in) {
+ return new ProvisionSubscriberId(in);
+ }
+
+ @Override
+ public ProvisionSubscriberId[] newArray(int size) {
+ return new ProvisionSubscriberId[size];
+ }
+ };
+
+ /**
+ * @hide
+ */
+ @Override
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * @return token.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public String getSubscriberId() {
+ return mSubscriberId;
+ }
+
+ /**
+ * @return carrierId.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public int getCarrierId() {
+ return mCarrierId;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("SubscriberId:");
+ sb.append(mSubscriberId);
+ sb.append(",");
+
+ sb.append("CarrierId:");
+ sb.append(mCarrierId);
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSubscriberId, mCarrierId);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ProvisionSubscriberId that = (ProvisionSubscriberId) o;
+ return mSubscriberId.equals(that.mSubscriberId) && mCarrierId
+ == that.mCarrierId;
+ }
+
+ private void readFromParcel(Parcel in) {
+ mSubscriberId = in.readString();
+ mCarrierId = in.readInt();
+ }
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 2a359cd..b518c60d 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -50,6 +50,7 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -233,6 +234,29 @@
public static final String KEY_NTN_SIGNAL_STRENGTH = "ntn_signal_strength";
/**
+ * Bundle key to get the response from
+ * {@link #requestProvisionSubscriberIds(Executor, OutcomeReceiver)}.
+ * @hide
+ */
+ public static final String KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN =
+ "request_provision_subscriber_id";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #requestIsProvisioned(String, Executor, OutcomeReceiver)}.
+ * @hide
+ */
+ public static final String KEY_IS_SATELLITE_PROVISIONED = "request_is_satellite_provisioned";
+
+ /**
+ * Bundle key to get the response from
+ * {@link #provisionSatellite(List, Executor, OutcomeReceiver)}.
+ * @hide
+ */
+ public static final String KEY_PROVISION_SATELLITE_TOKENS = "provision_satellite";
+
+
+ /**
* The request was successfully processed.
*/
@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
@@ -371,6 +395,24 @@
@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
public static final int SATELLITE_RESULT_MODEM_TIMEOUT = 24;
+ /**
+ * Telephony framework needs to access the current location of the device to perform the
+ * request. However, location in the settings is disabled by users.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ public static final int SATELLITE_RESULT_LOCATION_DISABLED = 25;
+
+ /**
+ * Telephony framework needs to access the current location of the device to perform the
+ * request. However, Telephony fails to fetch the current location from location service.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ public static final int SATELLITE_RESULT_LOCATION_NOT_AVAILABLE = 26;
+
/** @hide */
@IntDef(prefix = {"SATELLITE_RESULT_"}, value = {
SATELLITE_RESULT_SUCCESS,
@@ -397,7 +439,9 @@
SATELLITE_RESULT_REQUEST_IN_PROGRESS,
SATELLITE_RESULT_MODEM_BUSY,
SATELLITE_RESULT_ILLEGAL_STATE,
- SATELLITE_RESULT_MODEM_TIMEOUT
+ SATELLITE_RESULT_MODEM_TIMEOUT,
+ SATELLITE_RESULT_LOCATION_DISABLED,
+ SATELLITE_RESULT_LOCATION_NOT_AVAILABLE
})
@Retention(RetentionPolicy.SOURCE)
public @interface SatelliteResult {}
@@ -2560,6 +2604,179 @@
}
}
+ /**
+ * Request to get list of prioritized satellite subscriber ids to be used for provision.
+ *
+ * Satellite Gateway client will use these subscriber ids to register with satellite gateway
+ * service which identify user subscription with unique subscriber ids. These subscriber ids
+ * can be any unique value like iccid, imsi or msisdn which is decided based upon carrier
+ * requirements.
+ *
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ * If successful, the callback returns a list of tokens sorted in ascending priority order index
+ * 0 has the highest priority. Otherwise, it returns an error with a SatelliteException.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public void requestProvisionSubscriberIds(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<List<ProvisionSubscriberId>, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN)) {
+ List<ProvisionSubscriberId> list =
+ Collections.singletonList(resultData.getParcelable(
+ KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN,
+ ProvisionSubscriberId.class));
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(list)));
+ } else {
+ loge("KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestProvisionSubscriberIds(receiver);
+ } else {
+ loge("requestProvisionSubscriberIds() invalid telephony");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+ new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+ }
+ } catch (RemoteException ex) {
+ loge("requestProvisionSubscriberIds() RemoteException: " + ex);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+ new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+ }
+ }
+
+ /**
+ * Request to get provisioned status for given a satellite subscriber id.
+ *
+ * @param satelliteSubscriberId Satellite subscriber id requiring provisioned status check.
+ * @param executor The executor on which the callback will be called.
+ * @param callback callback.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public void requestIsProvisioned(@NonNull String satelliteSubscriberId,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+ Objects.requireNonNull(satelliteSubscriberId);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
+ boolean isIsProvisioned =
+ resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(isIsProvisioned)));
+ } else {
+ loge("KEY_REQUEST_PROVISION_TOKENS does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.requestIsProvisioned(satelliteSubscriberId, receiver);
+ } else {
+ loge("requestIsSatelliteProvisioned() invalid telephony");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+ new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+ }
+ } catch (RemoteException ex) {
+ loge("requestIsSatelliteProvisioned() RemoteException: " + ex);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+ new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+ }
+ }
+
+ /**
+ * Deliver the list of provisioned satellite subscriber ids.
+ *
+ * @param list List of ProvisionSubscriberId.
+ * @param executor The executor on which the callback will be called.
+ * @param callback The callback object to which the result will be delivered.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public void provisionSatellite(@NonNull List<ProvisionSubscriberId> list,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ ResultReceiver receiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_PROVISION_SATELLITE_TOKENS)) {
+ boolean isUpdated =
+ resultData.getBoolean(KEY_PROVISION_SATELLITE_TOKENS);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onResult(isUpdated)));
+ } else {
+ loge("KEY_REQUEST_PROVISION_TOKENS does not exist.");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
+ }
+ } else {
+ executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+ callback.onError(new SatelliteException(resultCode))));
+ }
+ }
+ };
+ telephony.provisionSatellite(list, receiver);
+ } else {
+ loge("provisionSatellite() invalid telephony");
+ executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+ new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+ }
+ } catch (RemoteException ex) {
+ loge("provisionSatellite() RemoteException: " + ex);
+ executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+ new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+ }
+ }
+
@Nullable
private static ITelephony getITelephony() {
ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
diff --git a/telephony/java/android/telephony/satellite/stub/ProvisionSubscriberId.aidl b/telephony/java/android/telephony/satellite/stub/ProvisionSubscriberId.aidl
new file mode 100644
index 0000000..2dc8ffb
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/ProvisionSubscriberId.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 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 android.telephony.satellite.stub;
+
+/**
+ * {@hide}
+ */
+parcelable ProvisionSubscriberId {
+ /** provision subscriberId */
+ String subscriberId;
+
+ /** carrier id */
+ int mCarrierId;
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 9b01b71..7be52ea 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -78,6 +78,7 @@
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.ProvisionSubscriberId;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.IBooleanConsumer;
@@ -3400,4 +3401,38 @@
* @hide
*/
void requestSatelliteSessionStats(int subId, in ResultReceiver receiver);
+
+ /**
+ * Request to get list of prioritized satellite subscriber ids to be used for provision.
+ *
+ * @param result The result receiver, which returns the list of prioritized satellite tokens
+ * to be used for provision if the request is successful or an error code if the request failed.
+ * @hide
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestProvisionSubscriberIds(in ResultReceiver receiver);
+
+ /**
+ * Request to get provisioned status for given a satellite subscriber id.
+ *
+ * @param satelliteSubscriberId Satellite subscriber id requiring provisioned status check.
+ * @param result The result receiver, which returns the provisioned status of the token if the
+ * request is successful or an error code if the request failed.
+ * @hide
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void requestIsProvisioned(in String satelliteSubscriberId, in ResultReceiver result);
+
+ /**
+ * Deliver the list of provisioned satellite subscriber ids.
+ *
+ * @param list List of provisioned satellite subscriber ids.
+ * @param result The result receiver that returns whether deliver success or fail.
+ * @hide
+ */
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+ + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+ void provisionSatellite(in List<ProvisionSubscriberId> list, in ResultReceiver result);
}
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index cf38bea..6bf7ff5 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -479,6 +479,15 @@
throw new UnsupportedOperationException();
}
+ /** @hide */
+ @Override
+ public void sendOrderedBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ String[] receiverPermissions, int appOp, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission,
String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
diff --git a/tests/Input/res/drawable/test_key_drawable.xml b/tests/Input/res/drawable/test_key_drawable.xml
new file mode 100644
index 0000000..2addf8f
--- /dev/null
+++ b/tests/Input/res/drawable/test_key_drawable.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2024 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.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="4dp" />
+ <solid android:color="#ffffffff"/>
+</shape>
\ No newline at end of file
diff --git a/tests/Input/res/drawable/test_modifier_drawable.xml b/tests/Input/res/drawable/test_modifier_drawable.xml
new file mode 100644
index 0000000..2addf8f
--- /dev/null
+++ b/tests/Input/res/drawable/test_modifier_drawable.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2024 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.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="4dp" />
+ <solid android:color="#ffffffff"/>
+</shape>
\ No newline at end of file
diff --git a/tests/Input/res/xml/keyboard_glyph_maps.xml b/tests/Input/res/xml/keyboard_glyph_maps.xml
new file mode 100644
index 0000000..d0616ff
--- /dev/null
+++ b/tests/Input/res/xml/keyboard_glyph_maps.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2024 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.
+ -->
+<keyboard-glyph-maps xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <keyboard-glyph-map
+ androidprv:glyphMap="@xml/test_glyph_map"
+ androidprv:vendorId="0x1234"
+ androidprv:productId="0x3456" />
+</keyboard-glyph-maps>
\ No newline at end of file
diff --git a/tests/Input/res/xml/test_glyph_map.xml b/tests/Input/res/xml/test_glyph_map.xml
new file mode 100644
index 0000000..7a7c1ac
--- /dev/null
+++ b/tests/Input/res/xml/test_glyph_map.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2024 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.
+ -->
+<keyboard-glyph-map xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <key-glyph
+ androidprv:keycode="KEYCODE_BACK"
+ androidprv:glyphDrawable="@drawable/test_key_drawable" />
+ <modifier-glyph
+ androidprv:modifier="META"
+ androidprv:glyphDrawable="@drawable/test_modifier_drawable" />
+ <function-row-key androidprv:keycode="KEYCODE_EMOJI_PICKER" />
+ <hardware-defined-shortcut
+ androidprv:keycode="KEYCODE_1"
+ androidprv:modifierState="FUNCTION"
+ androidprv:outKeycode="KEYCODE_BACK" />
+ <hardware-defined-shortcut
+ androidprv:keycode="KEYCODE_2"
+ androidprv:modifierState="FUNCTION|META"
+ androidprv:outKeycode="KEYCODE_HOME" />
+</keyboard-glyph-map>
\ No newline at end of file
diff --git a/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt
new file mode 100644
index 0000000..c073c7a
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2024 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.input
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import android.content.pm.ServiceInfo
+import android.hardware.input.IInputManager
+import android.hardware.input.InputManager
+import android.hardware.input.InputManagerGlobal
+import android.hardware.input.KeyGlyphMap.KeyCombination
+import android.os.Bundle
+import android.os.test.TestLooper
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.annotations.Presubmit
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.InputDevice
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import com.android.hardware.input.Flags
+import com.android.test.input.R
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.junit.MockitoJUnit
+
+/**
+ * Tests for custom keyboard glyph map configuration.
+ *
+ * Build/Install/Run:
+ * atest InputTests:KeyboardGlyphManagerTests
+ */
+@Presubmit
+class KeyboardGlyphManagerTests {
+
+ companion object {
+ const val DEVICE_ID = 1
+ const val VENDOR_ID = 0x1234
+ const val PRODUCT_ID = 0x3456
+ const val PACKAGE_NAME = "KeyboardLayoutManagerTests"
+ const val RECEIVER_NAME = "DummyReceiver"
+ }
+
+ @JvmField
+ @Rule(order = 0)
+ val setFlagsRule = SetFlagsRule()
+
+ @JvmField
+ @Rule(order = 1)
+ val mockitoRule = MockitoJUnit.rule()!!
+
+ @Mock
+ private lateinit var packageManager: PackageManager
+
+ @Mock
+ private lateinit var iInputManager: IInputManager
+
+ private lateinit var keyboardGlyphManager: KeyboardGlyphManager
+ private lateinit var context: Context
+ private lateinit var testLooper: TestLooper
+ private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
+ private lateinit var keyboardDevice: InputDevice
+
+ @Before
+ fun setup() {
+ context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
+ inputManagerGlobalSession = InputManagerGlobal.createTestSession(iInputManager)
+ testLooper = TestLooper()
+ keyboardGlyphManager = KeyboardGlyphManager(context, testLooper.looper)
+
+ setupInputDevices()
+ setupBroadcastReceiver()
+ keyboardGlyphManager.systemRunning()
+ testLooper.dispatchAll()
+ }
+
+ @After
+ fun tearDown() {
+ if (this::inputManagerGlobalSession.isInitialized) {
+ inputManagerGlobalSession.close()
+ }
+ }
+
+ private fun setupInputDevices() {
+ val inputManager = InputManager(context)
+ Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
+ .thenReturn(inputManager)
+
+ keyboardDevice = createKeyboard(DEVICE_ID, VENDOR_ID, PRODUCT_ID, 0, "", "")
+ Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
+ Mockito.`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardDevice)
+ }
+
+ private fun setupBroadcastReceiver() {
+ Mockito.`when`(context.packageManager).thenReturn(packageManager)
+
+ val info = createMockReceiver()
+ Mockito.`when`(packageManager.queryBroadcastReceiversAsUser(Mockito.any(), Mockito.anyInt(),
+ Mockito.anyInt())).thenReturn(listOf(info))
+ Mockito.`when`(packageManager.getReceiverInfo(Mockito.any(), Mockito.anyInt()))
+ .thenReturn(info.activityInfo)
+
+ val resources = context.resources
+ Mockito.`when`(
+ packageManager.getResourcesForApplication(
+ Mockito.any(
+ ApplicationInfo::class.java
+ )
+ )
+ ).thenReturn(resources)
+ }
+
+ private fun createMockReceiver(): ResolveInfo {
+ val info = ResolveInfo()
+ info.activityInfo = ActivityInfo()
+ info.activityInfo.packageName = PACKAGE_NAME
+ info.activityInfo.name = RECEIVER_NAME
+ info.activityInfo.applicationInfo = ApplicationInfo()
+ info.activityInfo.metaData = Bundle()
+ info.activityInfo.metaData.putInt(
+ InputManager.META_DATA_KEYBOARD_GLYPH_MAPS,
+ R.xml.keyboard_glyph_maps
+ )
+ info.serviceInfo = ServiceInfo()
+ info.serviceInfo.packageName = PACKAGE_NAME
+ info.serviceInfo.name = RECEIVER_NAME
+ return info
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_GLYPH_MAP)
+ fun testGlyphMapsLoaded() {
+ assertNotNull(
+ "Glyph map for test keyboard(deviceId=$DEVICE_ID) must exist",
+ keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID)
+ )
+ assertNull(
+ "Glyph map for non-existing keyboard must be null",
+ keyboardGlyphManager.getKeyGlyphMap(-2)
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_GLYPH_MAP)
+ fun testGlyphMapCorrectlyLoaded() {
+ val glyphMap = keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID)
+ // Test glyph map used in this test: {@see test_glyph_map.xml}
+ assertNotNull(glyphMap!!.getDrawableForKeycode(context, KeyEvent.KEYCODE_BACK))
+
+ assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_LEFT))
+ assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_RIGHT))
+
+ val functionRowKeys = glyphMap.functionRowKeys
+ assertEquals(1, functionRowKeys.size)
+ assertEquals(KeyEvent.KEYCODE_EMOJI_PICKER, functionRowKeys[0])
+
+ val hardwareShortcuts = glyphMap.hardwareShortcuts
+ assertEquals(2, hardwareShortcuts.size)
+ assertEquals(
+ KeyEvent.KEYCODE_BACK,
+ hardwareShortcuts[KeyCombination(KeyEvent.META_FUNCTION_ON, KeyEvent.KEYCODE_1)]
+ )
+ assertEquals(
+ KeyEvent.KEYCODE_HOME,
+ hardwareShortcuts[
+ KeyCombination(
+ KeyEvent.META_FUNCTION_ON or KeyEvent.META_META_ON,
+ KeyEvent.KEYCODE_2
+ )
+ ]
+ )
+ }
+}
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index 93f97cb..301c0e6 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -58,7 +58,7 @@
import java.io.IOException
import java.io.InputStream
-private fun createKeyboard(
+fun createKeyboard(
deviceId: Int,
vendorId: Int,
productId: Int,
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
index fff1dd1..0db0d95 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
@@ -16,6 +16,8 @@
package com.android.server.inputmethod.multisessiontest;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.getResponderUserId;
@@ -28,24 +30,33 @@
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.UiAutomation;
import android.content.ComponentName;
+import android.content.Context;
import android.os.Bundle;
+import android.os.UserHandle;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
import androidx.test.core.app.ActivityScenario;
import com.android.bedstead.harrier.BedsteadJUnit4;
import com.android.bedstead.harrier.DeviceState;
+import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.IOException;
+import java.util.List;
+
@RunWith(BedsteadJUnit4.class)
-@Ignore("b/345557347")
public final class ConcurrentMultiUserTest {
@ClassRule
@@ -55,6 +66,10 @@
private static final ComponentName TEST_ACTIVITY = new ComponentName(
getInstrumentation().getTargetContext().getPackageName(),
MainActivity.class.getName());
+ private final Context mContext = getInstrumentation().getTargetContext();
+ private final InputMethodManager mInputMethodManager =
+ mContext.getSystemService(InputMethodManager.class);
+ private final UiAutomation mUiAutomation = getInstrumentation().getUiAutomation();
private ActivityScenario<MainActivity> mActivityScenario;
private MainActivity mActivity;
@@ -69,10 +84,12 @@
// Launch driver activity.
mActivityScenario = ActivityScenario.launch(MainActivity.class);
mActivityScenario.onActivity(activity -> mActivity = activity);
+ mUiAutomation.adoptShellPermissionIdentity(INTERACT_ACROSS_USERS_FULL);
}
@After
public void tearDown() {
+ mUiAutomation.dropShellPermissionIdentity();
if (mActivityScenario != null) {
mActivityScenario.close();
}
@@ -87,6 +104,58 @@
assertPassengerImeHidden();
}
+ @Test
+ public void imeListNotEmpty() {
+ List<InputMethodInfo> driverImeList = mInputMethodManager.getInputMethodList();
+ assertWithMessage("Driver IME list shouldn't be empty")
+ .that(driverImeList.isEmpty()).isFalse();
+
+ List<InputMethodInfo> passengerImeList =
+ mInputMethodManager.getInputMethodListAsUser(mPeerUserId);
+ assertWithMessage("Passenger IME list shouldn't be empty")
+ .that(passengerImeList.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void enabledImeListNotEmpty() {
+ List<InputMethodInfo> driverEnabledImeList =
+ mInputMethodManager.getEnabledInputMethodList();
+ assertWithMessage("Driver enabled IME list shouldn't be empty")
+ .that(driverEnabledImeList.isEmpty()).isFalse();
+
+ List<InputMethodInfo> passengerEnabledImeList =
+ mInputMethodManager.getEnabledInputMethodListAsUser(UserHandle.of(mPeerUserId));
+ assertWithMessage("Passenger enabled IME list shouldn't be empty")
+ .that(passengerEnabledImeList.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void currentImeNotNull() {
+ InputMethodInfo driverIme = mInputMethodManager.getCurrentInputMethodInfo();
+ assertWithMessage("Driver IME shouldn't be null").that(driverIme).isNotNull();
+
+ InputMethodInfo passengerIme =
+ mInputMethodManager.getCurrentInputMethodInfoAsUser(UserHandle.of(mPeerUserId));
+ assertWithMessage("Passenger IME shouldn't be null")
+ .that(passengerIme).isNotNull();
+ }
+
+ @Test
+ public void enableDisableImePerUser() throws IOException {
+ UserHandle driver = UserHandle.of(mContext.getUserId());
+ UserHandle passenger = UserHandle.of(mPeerUserId);
+ enableDisableImeForUser(driver, passenger);
+ enableDisableImeForUser(passenger, driver);
+ }
+
+ @Test
+ public void setImePerUser() throws IOException {
+ UserHandle driver = UserHandle.of(mContext.getUserId());
+ UserHandle passenger = UserHandle.of(mPeerUserId);
+ setImeForUser(driver, passenger);
+ setImeForUser(passenger, driver);
+ }
+
private void assertDriverImeHidden() {
assertWithMessage("Driver IME should be hidden")
.that(mActivity.isMyImeVisible()).isFalse();
@@ -104,4 +173,89 @@
private void showDriverImeAndAssert() {
mActivity.showMyImeAndWait();
}
+
+ /**
+ * Disables/enables IME for {@code user1}, then verifies that the IME settings for {@code user1}
+ * has changed as expected and {@code user2} stays the same.
+ */
+ private void enableDisableImeForUser(UserHandle user1, UserHandle user2) throws IOException {
+ List<InputMethodInfo> user1EnabledImeList =
+ mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+ List<InputMethodInfo> user2EnabledImeList =
+ mInputMethodManager.getEnabledInputMethodListAsUser(user2);
+
+ // Disable an IME for user1.
+ InputMethodInfo imeToDisable = user1EnabledImeList.get(0);
+ SystemUtil.runShellCommand(mUiAutomation,
+ "ime disable --user " + user1.getIdentifier() + " " + imeToDisable.getId());
+ List<InputMethodInfo> user1EnabledImeList2 =
+ mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+ List<InputMethodInfo> user2EnabledImeList2 =
+ mInputMethodManager.getEnabledInputMethodListAsUser(user2);
+ assertWithMessage("User " + user1.getIdentifier() + " IME " + imeToDisable.getId()
+ + " should be disabled")
+ .that(user1EnabledImeList2.contains(imeToDisable)).isFalse();
+ assertWithMessage("Disabling user " + user1.getIdentifier()
+ + " IME shouldn't affect user " + user2.getIdentifier())
+ .that(user2EnabledImeList2.containsAll(user2EnabledImeList)
+ && user2EnabledImeList.containsAll(user2EnabledImeList2))
+ .isTrue();
+
+ // Enable the IME.
+ SystemUtil.runShellCommand(mUiAutomation,
+ "ime enable --user " + user1.getIdentifier() + " " + imeToDisable.getId());
+ List<InputMethodInfo> user1EnabledImeList3 =
+ mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+ List<InputMethodInfo> user2EnabledImeList3 =
+ mInputMethodManager.getEnabledInputMethodListAsUser(user2);
+ assertWithMessage("User " + user1.getIdentifier() + " IME " + imeToDisable.getId()
+ + " should be enabled").that(user1EnabledImeList3.contains(imeToDisable)).isTrue();
+ assertWithMessage("Enabling user " + user1.getIdentifier()
+ + " IME shouldn't affect user " + user2.getIdentifier())
+ .that(user2EnabledImeList2.containsAll(user2EnabledImeList3)
+ && user2EnabledImeList3.containsAll(user2EnabledImeList2))
+ .isTrue();
+ }
+
+ /**
+ * Sets/resets IME for {@code user1}, then verifies that the IME settings for {@code user1}
+ * has changed as expected and {@code user2} stays the same.
+ */
+ private void setImeForUser(UserHandle user1, UserHandle user2) throws IOException {
+ // Reset IME for user1.
+ SystemUtil.runShellCommand(mUiAutomation,
+ "ime reset --user " + user1.getIdentifier());
+
+ List<InputMethodInfo> user1EnabledImeList =
+ mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+ assumeTrue("There must be at least two IME to test", user1EnabledImeList.size() >= 2);
+ InputMethodInfo user1Ime = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
+ InputMethodInfo user2Ime = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
+
+ // Set to another IME for user1.
+ InputMethodInfo anotherIme = null;
+ for (InputMethodInfo info : user1EnabledImeList) {
+ if (!info.equals(user1Ime)) {
+ anotherIme = info;
+ }
+ }
+ SystemUtil.runShellCommand(mUiAutomation,
+ "ime set --user " + user1.getIdentifier() + " " + anotherIme.getId());
+ InputMethodInfo user1Ime2 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
+ InputMethodInfo user2Ime2 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
+ assertWithMessage("The current IME for user " + user1.getIdentifier() + " is wrong")
+ .that(user1Ime2).isEqualTo(anotherIme);
+ assertWithMessage("The current IME for user " + user2.getIdentifier() + " shouldn't change")
+ .that(user2Ime2).isEqualTo(user2Ime);
+
+ // Reset IME for user1.
+ SystemUtil.runShellCommand(mUiAutomation,
+ "ime reset --user " + user1.getIdentifier());
+ InputMethodInfo user1Ime3 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
+ InputMethodInfo user2Ime3 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
+ assertWithMessage("The current IME for user " + user1.getIdentifier() + " is wrong")
+ .that(user1Ime3).isEqualTo(user1Ime);
+ assertWithMessage("The current IME for user " + user2.getIdentifier() + " shouldn't change")
+ .that(user2Ime3).isEqualTo(user2Ime);
+ }
}
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
index f126000..3c97b79 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
@@ -87,11 +87,13 @@
}
if (!mImm.showSoftInput(mEditor, /* flags= */ 0)) {
Log.e(TAG, String.format("Failed to show my IME as user %d, "
- + "mEditor:focused=%b,hasWindowFocus=%b", getUserId(),
+ + "mEditor:focused=%b,hasWindowFocus=%b",
+ Process.myUserHandle().getIdentifier(),
mEditor.isFocused(), mEditor.hasWindowFocus()));
}
});
PollingCheck.waitFor(WAIT_IME_TIMEOUT_MS, () -> isMyImeVisible(),
- String.format("My IME (user %d) didn't show up", getUserId()));
+ String.format("My IME (user %d) didn't show up",
+ Process.myUserHandle().getIdentifier()));
}
}
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 031dd5b..9b8c3b3 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -836,6 +836,28 @@
return 1;
}
+ // Parse the feature flag values. An argument that starts with '@' points to a file to read flag
+ // values from.
+ std::vector<std::string> all_feature_flags_args;
+ for (const std::string& arg : feature_flags_args_) {
+ if (util::StartsWith(arg, "@")) {
+ const std::string path = arg.substr(1, arg.size() - 1);
+ std::string error;
+ if (!file::AppendArgsFromFile(path, &all_feature_flags_args, &error)) {
+ context.GetDiagnostics()->Error(android::DiagMessage(path) << error);
+ return 1;
+ }
+ } else {
+ all_feature_flags_args.push_back(arg);
+ }
+ }
+
+ for (const std::string& arg : all_feature_flags_args) {
+ if (!ParseFeatureFlagsParameter(arg, context.GetDiagnostics(), &options_.feature_flag_values)) {
+ return 1;
+ }
+ }
+
return Compile(&context, file_collection.get(), archive_writer.get(), options_);
}
diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h
index 61c5b60..70c8791 100644
--- a/tools/aapt2/cmd/Compile.h
+++ b/tools/aapt2/cmd/Compile.h
@@ -24,6 +24,7 @@
#include "Command.h"
#include "ResourceTable.h"
#include "androidfw/IDiagnostics.h"
+#include "cmd/Util.h"
#include "format/Archive.h"
#include "process/IResourceTableConsumer.h"
@@ -45,6 +46,7 @@
bool preserve_visibility_of_styleables = false;
bool verbose = false;
std::optional<std::string> product_;
+ FeatureFlagValues feature_flag_values;
};
/** Parses flags and compiles resources to be used in linking. */
@@ -92,6 +94,12 @@
"Leave only resources specific to the given product. All "
"other resources (including defaults) are removed.",
&options_.product_);
+ AddOptionalFlagList("--feature-flags",
+ "Specify the values of feature flags. The pairs in the argument\n"
+ "are separated by ',' the name is separated from the value by '='.\n"
+ "The name can have a suffix of ':ro' to indicate it is read only."
+ "Example: \"flag1=true,flag2:ro=false,flag3=\" (flag3 has no given value).",
+ &feature_flags_args_);
}
int Action(const std::vector<std::string>& args) override;
@@ -101,6 +109,7 @@
CompileOptions options_;
std::optional<std::string> visibility_;
std::optional<std::string> trace_folder_;
+ std::vector<std::string> feature_flags_args_;
};
int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer,
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index 8fe414f..2f17853 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -332,8 +332,9 @@
AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
AddOptionalFlagList("--feature-flags",
"Specify the values of feature flags. The pairs in the argument\n"
- "are separated by ',' and the name is separated from the value by '='.\n"
- "Example: \"flag1=true,flag2=false,flag3=\" (flag3 has no given value).",
+ "are separated by ',' the name is separated from the value by '='.\n"
+ "The name can have a suffix of ':ro' to indicate it is read only."
+ "Example: \"flag1=true,flag2:ro=false,flag3=\" (flag3 has no given value).",
&feature_flags_args_);
AddOptionalSwitch("--non-updatable-system",
"Mark the app as a non-updatable system app. This inserts\n"
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index 678d846..e839fc1 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -128,7 +128,7 @@
if (parts.size() > 2) {
diag->Error(android::DiagMessage()
<< "Invalid feature flag and optional value '" << flag_and_value
- << "'. Must be in the format 'flag_name[=true|false]");
+ << "'. Must be in the format 'flag_name[:ro][=true|false]");
return false;
}
@@ -137,6 +137,25 @@
diag->Error(android::DiagMessage() << "No name given for one or more flags in: " << arg);
return false;
}
+ std::vector<std::string> name_parts = util::Split(flag_name, ':');
+ if (name_parts.size() > 2) {
+ diag->Error(android::DiagMessage()
+ << "Invalid feature flag and optional value '" << flag_and_value
+ << "'. Must be in the format 'flag_name[:ro][=true|false]");
+ return false;
+ }
+ flag_name = name_parts[0];
+ bool read_only = false;
+ if (name_parts.size() == 2) {
+ if (name_parts[1] == "ro") {
+ read_only = true;
+ } else {
+ diag->Error(android::DiagMessage()
+ << "Invalid feature flag and optional value '" << flag_and_value
+ << "'. Must be in the format 'flag_name[:ro][=true|false]");
+ return false;
+ }
+ }
std::optional<bool> flag_value = {};
if (parts.size() == 2) {
@@ -151,13 +170,13 @@
}
}
- if (auto [it, inserted] =
- out_feature_flag_values->try_emplace(std::string(flag_name), flag_value);
+ auto ffp = FeatureFlagProperties{read_only, flag_value};
+ if (auto [it, inserted] = out_feature_flag_values->try_emplace(std::string(flag_name), ffp);
!inserted) {
// We are allowing the same flag to appear multiple times, last value wins.
diag->Note(android::DiagMessage()
<< "Value for feature flag '" << flag_name << "' was given more than once");
- it->second = flag_value;
+ it->second = ffp;
}
}
return true;
diff --git a/tools/aapt2/cmd/Util.h b/tools/aapt2/cmd/Util.h
index 9ece5dd..6b8813b 100644
--- a/tools/aapt2/cmd/Util.h
+++ b/tools/aapt2/cmd/Util.h
@@ -37,7 +37,17 @@
namespace aapt {
-using FeatureFlagValues = std::map<std::string, std::optional<bool>, std::less<>>;
+struct FeatureFlagProperties {
+ bool read_only;
+ std::optional<bool> enabled;
+
+ FeatureFlagProperties(bool ro, std::optional<bool> e) : read_only(ro), enabled(e) {
+ }
+
+ bool operator==(const FeatureFlagProperties&) const = default;
+};
+
+using FeatureFlagValues = std::map<std::string, FeatureFlagProperties, std::less<>>;
// Parses a configuration density (ex. hdpi, xxhdpi, 234dpi, anydpi, etc).
// Returns Nothing and logs a human friendly error message if the string was not legal.
diff --git a/tools/aapt2/cmd/Util_test.cpp b/tools/aapt2/cmd/Util_test.cpp
index 723d87e..35bc637 100644
--- a/tools/aapt2/cmd/Util_test.cpp
+++ b/tools/aapt2/cmd/Util_test.cpp
@@ -383,21 +383,25 @@
TEST(UtilTest, ParseFeatureFlagsParameter_DuplicateFlag) {
auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
FeatureFlagValues feature_flag_values;
- ASSERT_TRUE(
- ParseFeatureFlagsParameter("foo=true,bar=true,foo=false", diagnostics, &feature_flag_values));
- EXPECT_THAT(feature_flag_values, UnorderedElementsAre(Pair("foo", std::optional<bool>(false)),
- Pair("bar", std::optional<bool>(true))));
+ ASSERT_TRUE(ParseFeatureFlagsParameter("foo=true,bar=true,foo:ro=false", diagnostics,
+ &feature_flag_values));
+ EXPECT_THAT(
+ feature_flag_values,
+ UnorderedElementsAre(Pair("foo", FeatureFlagProperties{true, std::optional<bool>(false)}),
+ Pair("bar", FeatureFlagProperties{false, std::optional<bool>(true)})));
}
TEST(UtilTest, ParseFeatureFlagsParameter_Valid) {
auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
FeatureFlagValues feature_flag_values;
- ASSERT_TRUE(ParseFeatureFlagsParameter("foo= true, bar =FALSE,baz=, quux", diagnostics,
+ ASSERT_TRUE(ParseFeatureFlagsParameter("foo= true, bar:ro =FALSE,baz=, quux", diagnostics,
&feature_flag_values));
- EXPECT_THAT(feature_flag_values,
- UnorderedElementsAre(Pair("foo", std::optional<bool>(true)),
- Pair("bar", std::optional<bool>(false)),
- Pair("baz", std::nullopt), Pair("quux", std::nullopt)));
+ EXPECT_THAT(
+ feature_flag_values,
+ UnorderedElementsAre(Pair("foo", FeatureFlagProperties{false, std::optional<bool>(true)}),
+ Pair("bar", FeatureFlagProperties{true, std::optional<bool>(false)}),
+ Pair("baz", FeatureFlagProperties{false, std::nullopt}),
+ Pair("quux", FeatureFlagProperties{false, std::nullopt})));
}
TEST (UtilTest, AdjustSplitConstraintsForMinSdk) {
diff --git a/tools/aapt2/link/FeatureFlagsFilter.cpp b/tools/aapt2/link/FeatureFlagsFilter.cpp
index fdf3f74..9d40db5 100644
--- a/tools/aapt2/link/FeatureFlagsFilter.cpp
+++ b/tools/aapt2/link/FeatureFlagsFilter.cpp
@@ -63,12 +63,11 @@
flag_name = flag_name.substr(1);
}
- if (auto it = feature_flag_values_.find(std::string(flag_name));
- it != feature_flag_values_.end()) {
- if (it->second.has_value()) {
+ if (auto it = feature_flag_values_.find(flag_name); it != feature_flag_values_.end()) {
+ if (it->second.enabled.has_value()) {
if (options_.remove_disabled_elements) {
// Remove if flag==true && attr=="!flag" (negated) OR flag==false && attr=="flag"
- return *it->second == negated;
+ return *it->second.enabled == negated;
}
} else if (options_.flags_must_have_value) {
diagnostics_->Error(android::DiagMessage(node->line_number)
diff --git a/tools/aapt2/link/FeatureFlagsFilter_test.cpp b/tools/aapt2/link/FeatureFlagsFilter_test.cpp
index 53086cc..2db2899 100644
--- a/tools/aapt2/link/FeatureFlagsFilter_test.cpp
+++ b/tools/aapt2/link/FeatureFlagsFilter_test.cpp
@@ -48,7 +48,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" />
</manifest>)EOF",
- {{"flag", false}});
+ {{"flag", FeatureFlagProperties{false, false}}});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -60,7 +60,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="flag" />
</manifest>)EOF",
- {{"flag", false}});
+ {{"flag", FeatureFlagProperties{false, false}}});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -73,7 +73,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="!flag" />
</manifest>)EOF",
- {{"flag", true}});
+ {{"flag", FeatureFlagProperties{false, true}}});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -86,7 +86,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="flag" />
</manifest>)EOF",
- {{"flag", true}});
+ {{"flag", FeatureFlagProperties{false, true}}});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -102,7 +102,7 @@
<permission android:name="FOO" android:featureFlag="flag"
android:protectionLevel="dangerous" />
</manifest>)EOF",
- {{"flag", true}});
+ {{"flag", FeatureFlagProperties{false, true}}});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -123,7 +123,7 @@
</activity>
</application>
</manifest>)EOF",
- {{"flag", true}});
+ {{"flag", FeatureFlagProperties{false, true}}});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -145,7 +145,7 @@
</activity>
</application>
</manifest>)EOF",
- {{"flag", true}});
+ {{"flag", FeatureFlagProperties{false, true}}});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -162,7 +162,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag=" " />
</manifest>)EOF",
- {{"flag", false}});
+ {{"flag", FeatureFlagProperties{false, false}}});
ASSERT_THAT(doc, IsNull());
}
@@ -171,7 +171,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="flag" />
</manifest>)EOF",
- {{"flag", std::nullopt}});
+ {{"flag", FeatureFlagProperties{false, std::nullopt}}});
ASSERT_THAT(doc, IsNull());
}
@@ -180,7 +180,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="unrecognized" />
</manifest>)EOF",
- {{"flag", true}});
+ {{"flag", FeatureFlagProperties{false, true}}});
ASSERT_THAT(doc, IsNull());
}
@@ -190,7 +190,7 @@
<permission android:name="FOO" android:featureFlag="bar" />
<permission android:name="FOO" android:featureFlag="unrecognized" />
</manifest>)EOF",
- {{"flag", std::nullopt}});
+ {{"flag", FeatureFlagProperties{false, std::nullopt}}});
ASSERT_THAT(doc, IsNull());
}
@@ -199,7 +199,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="flag" />
</manifest>)EOF",
- {{"flag", false}}, {.remove_disabled_elements = false});
+ {{"flag", FeatureFlagProperties{false, false}}},
+ {.remove_disabled_elements = false});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -212,7 +213,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="flag" />
</manifest>)EOF",
- {{"flag", std::nullopt}}, {.flags_must_have_value = false});
+ {{"flag", FeatureFlagProperties{false, std::nullopt}}},
+ {.flags_must_have_value = false});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
@@ -225,7 +227,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
<permission android:name="FOO" android:featureFlag="unrecognized" />
</manifest>)EOF",
- {{"flag", true}}, {.fail_on_unrecognized_flags = false});
+ {{"flag", FeatureFlagProperties{false, true}}},
+ {.fail_on_unrecognized_flags = false});
ASSERT_THAT(doc, NotNull());
auto root = doc->root.get();
ASSERT_THAT(root, NotNull());
diff --git a/tools/lint/OWNERS b/tools/lint/OWNERS
index 33e237d..8e4569e 100644
--- a/tools/lint/OWNERS
+++ b/tools/lint/OWNERS
@@ -1,4 +1,5 @@
-brufino@google.com
+mattgilbride@google.com
+azharaa@google.com
jsharkey@google.com
per-file *CallingSettingsNonUserGetterMethods* = file:/packages/SettingsProvider/OWNERS
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 0f1373c..2d5b50b 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -17,7 +17,6 @@
package com.android.protolog.tool
import com.android.internal.protolog.common.LogLevel
-import com.android.internal.protolog.common.ProtoLog
import com.android.internal.protolog.common.ProtoLogToolInjected
import com.android.protolog.tool.CommandOptions.Companion.USAGE
import com.github.javaparser.ParseProblemException
@@ -61,6 +60,8 @@
const val PROTOLOG_IMPL_SRC_PATH =
"frameworks/base/core/java/com/android/internal/protolog/ProtoLogImpl.java"
+ private const val PROTOLOG_CLASS_NAME = "ProtoLog"; // ProtoLog::class.java.simpleName
+
data class LogCall(
val messageString: String,
val logLevel: LogLevel,
@@ -124,7 +125,7 @@
val text = injector.readText(file)
val outSrc = try {
val code = tryParse(text, path)
- if (containsProtoLogText(text, ProtoLog::class.java.simpleName)) {
+ if (containsProtoLogText(text, PROTOLOG_CLASS_NAME)) {
transformer.processClass(text, path, packagePath(file, code), code)
} else {
text
diff --git a/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
index 822118c..2a83677 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
@@ -35,7 +35,7 @@
val output = run(
srcs = mapOf("frameworks/base/org/example/Example.java" to """
package org.example;
- import com.android.internal.protolog.common.ProtoLog;
+ import com.android.internal.protolog.ProtoLog;
import static com.android.internal.protolog.ProtoLogGroup.GROUP;
class Example {
@@ -48,7 +48,7 @@
""".trimIndent()),
logGroup = LogGroup("GROUP", true, false, "TAG_GROUP"),
commandOptions = CommandOptions(arrayOf("transform-protolog-calls",
- "--protolog-class", "com.android.internal.protolog.common.ProtoLog",
+ "--protolog-class", "com.android.internal.protolog.ProtoLog",
"--loggroups-class", "com.android.internal.protolog.ProtoLogGroup",
"--loggroups-jar", "not_required.jar",
"--viewer-config-file-path", "not_required.pb",
@@ -69,7 +69,7 @@
val output = run(
srcs = mapOf("frameworks/base/org/example/Example.java" to """
package org.example;
- import com.android.internal.protolog.common.ProtoLog;
+ import com.android.internal.protolog.ProtoLog;
import static com.android.internal.protolog.ProtoLogGroup.GROUP;
class Example {
@@ -82,7 +82,7 @@
""".trimIndent()),
logGroup = LogGroup("GROUP", true, false, "TAG_GROUP"),
commandOptions = CommandOptions(arrayOf("generate-viewer-config",
- "--protolog-class", "com.android.internal.protolog.common.ProtoLog",
+ "--protolog-class", "com.android.internal.protolog.ProtoLog",
"--loggroups-class", "com.android.internal.protolog.ProtoLogGroup",
"--loggroups-jar", "not_required.jar",
"--viewer-config-type", "json",
diff --git a/wifi/java/src/android/net/wifi/WifiMigration.java b/wifi/java/src/android/net/wifi/WifiMigration.java
index 4fabc0b..1a20a12 100644
--- a/wifi/java/src/android/net/wifi/WifiMigration.java
+++ b/wifi/java/src/android/net/wifi/WifiMigration.java
@@ -19,16 +19,23 @@
import static android.os.Environment.getDataMiscCeDirectory;
import static android.os.Environment.getDataMiscDirectory;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.Context;
+import android.net.wifi.flags.Flags;
+import android.os.Binder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.Process;
+import android.os.ServiceSpecificException;
import android.os.UserHandle;
import android.provider.Settings;
+import android.security.legacykeystore.ILegacyKeystore;
import android.util.AtomicFile;
+import android.util.Log;
import android.util.SparseArray;
import java.io.File;
@@ -36,7 +43,11 @@
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* Class used to provide one time hooks for existing OEM devices to migrate their config store
@@ -45,6 +56,8 @@
*/
@SystemApi
public final class WifiMigration {
+ private static final String TAG = "WifiMigration";
+
/**
* Directory to read the wifi config store files from under.
*/
@@ -555,4 +568,49 @@
return data;
}
+
+ /**
+ * Migrate any certificates in Legacy Keystore to the newer WifiBlobstore database.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_LEGACY_KEYSTORE_TO_WIFI_BLOBSTORE_MIGRATION)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static void migrateLegacyKeystoreToWifiBlobstore() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ ILegacyKeystore legacyKeystore = WifiBlobStore.getLegacyKeystore();
+ String[] legacyAliases = legacyKeystore.list("", Process.WIFI_UID);
+ if (legacyAliases == null || legacyAliases.length == 0) {
+ Log.i(TAG, "No aliases need to be migrated");
+ return;
+ }
+
+ WifiBlobStore wifiBlobStore = WifiBlobStore.getInstance();
+ List<String> blobstoreAliasList = Arrays.asList(wifiBlobStore.list(""));
+ Set<String> blobstoreAliases = new HashSet<>();
+ blobstoreAliases.addAll(blobstoreAliasList);
+
+ for (String legacyAlias : legacyAliases) {
+ // Only migrate if the alias is not already in WifiBlobstore,
+ // since WifiBlobstore should already contain the latest value.
+ if (!blobstoreAliases.contains(legacyAlias)) {
+ byte[] value = legacyKeystore.get(legacyAlias, Process.WIFI_UID);
+ wifiBlobStore.put(legacyAlias, value);
+ }
+ legacyKeystore.remove(legacyAlias, Process.WIFI_UID);
+ }
+ Log.i(TAG, "Successfully migrated aliases from Legacy Keystore");
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ILegacyKeystore.ERROR_SYSTEM_ERROR) {
+ Log.i(TAG, "Legacy Keystore service has been deprecated");
+ } else {
+ Log.e(TAG, "Encountered an exception while migrating aliases. " + e);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Encountered an exception while migrating aliases. " + e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/WifiMigrationTest.java b/wifi/tests/src/android/net/wifi/WifiMigrationTest.java
new file mode 100644
index 0000000..8a5912f
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiMigrationTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2024 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 android.net.wifi;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.validateMockitoUsage;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import android.security.legacykeystore.ILegacyKeystore;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+
+/**
+ * Unit tests for {@link WifiMigration}.
+ */
+public class WifiMigrationTest {
+ public static final String TEST_ALIAS = "someAliasString";
+ public static final byte[] TEST_VALUE = new byte[]{10, 11, 12};
+
+ @Mock private ILegacyKeystore mLegacyKeystore;
+ @Mock private WifiBlobStore mWifiBlobStore;
+
+ private MockitoSession mSession;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mSession = ExtendedMockito.mockitoSession()
+ .mockStatic(WifiBlobStore.class, withSettings().lenient())
+ .startMocking();
+ when(WifiBlobStore.getLegacyKeystore()).thenReturn(mLegacyKeystore);
+ when(WifiBlobStore.getInstance()).thenReturn(mWifiBlobStore);
+ when(mLegacyKeystore.get(anyString(), anyInt())).thenReturn(TEST_VALUE);
+ }
+
+ @After
+ public void cleanup() {
+ validateMockitoUsage();
+ if (mSession != null) {
+ mSession.finishMocking();
+ }
+ }
+
+ /**
+ * Verify that the Keystore migration method returns immediately if no aliases
+ * are found in Legacy Keystore.
+ */
+ @Test
+ public void testKeystoreMigrationNoLegacyAliases() throws Exception {
+ when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(new String[0]);
+ WifiMigration.migrateLegacyKeystoreToWifiBlobstore();
+ verify(mLegacyKeystore).list(anyString(), anyInt());
+ verifyNoMoreInteractions(mLegacyKeystore, mWifiBlobStore);
+ }
+
+ /**
+ * Verify that if all aliases in Legacy Keystore are unique to that database,
+ * all aliases are migrated to WifiBlobstore.
+ */
+ @Test
+ public void testKeystoreMigrationUniqueLegacyAliases() throws Exception {
+ String[] legacyAliases = new String[]{TEST_ALIAS + "1", TEST_ALIAS + "2"};
+ String[] blobstoreAliases = new String[0];
+ when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(legacyAliases);
+ when(mWifiBlobStore.list(anyString())).thenReturn(blobstoreAliases);
+
+ WifiMigration.migrateLegacyKeystoreToWifiBlobstore();
+ verify(mWifiBlobStore, times(legacyAliases.length)).put(anyString(), any(byte[].class));
+ }
+
+ /**
+ * Verify that if some aliases are shared between Legacy Keystore and WifiBlobstore,
+ * only the ones unique to Legacy Keystore are migrated.
+ */
+ @Test
+ public void testKeystoreMigrationDuplicateLegacyAliases() throws Exception {
+ String uniqueLegacyAlias = TEST_ALIAS + "1";
+ String[] blobstoreAliases = new String[]{TEST_ALIAS + "2", TEST_ALIAS + "3"};
+ String[] legacyAliases =
+ new String[]{blobstoreAliases[0], blobstoreAliases[1], uniqueLegacyAlias};
+ when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(legacyAliases);
+ when(mWifiBlobStore.list(anyString())).thenReturn(blobstoreAliases);
+
+ // Expect that only the unique legacy alias is migrated to the blobstore
+ WifiMigration.migrateLegacyKeystoreToWifiBlobstore();
+ verify(mWifiBlobStore).list(anyString());
+ verify(mWifiBlobStore).put(eq(uniqueLegacyAlias), any(byte[].class));
+ verifyNoMoreInteractions(mWifiBlobStore);
+ }
+}
diff --git a/wifi/wifi.aconfig b/wifi/wifi.aconfig
index c5bc039..c1effe1 100644
--- a/wifi/wifi.aconfig
+++ b/wifi/wifi.aconfig
@@ -17,3 +17,11 @@
description: "Control the API that allows setting / reading the NetworkProviderInfo's battery charging status"
bug: "305067231"
}
+
+flag {
+ name: "legacy_keystore_to_wifi_blobstore_migration"
+ is_exported: true
+ namespace: "wifi"
+ description: "Add API to migrate all values from Legacy Keystore to the new Wifi Blobstore database"
+ bug: "332560152"
+}