Merge "Distinguish null blobs in SQLiteRawStatement" into main
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
index a4128a3..459c286 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
@@ -22,12 +22,12 @@
import android.util.Log;
import java.util.ArrayList;
-import java.util.concurrent.TimeoutException;
// Based on //platform/frameworks/base/apct-tests/perftests/utils/BenchmarkState.java
public class BenchmarkRunner {
private static final String TAG = BenchmarkRunner.class.getSimpleName();
- private static final int TIMEOUT_IN_SECONDS = 45;
+ private static final long COOL_OFF_PERIOD_MS = 1000;
+ private static final int CPU_IDLE_TIMEOUT_MS = 60 * 1000;
private static final int CPU_IDLE_THRESHOLD_PERCENTAGE = 90;
private static final int NUM_ITERATIONS = 4;
@@ -82,6 +82,7 @@
}
private void prepareForNextRun() {
+ SystemClock.sleep(COOL_OFF_PERIOD_MS);
waitCoolDownPeriod();
mStartTimeNs = System.nanoTime();
mPausedDurationNs = 0;
@@ -165,42 +166,42 @@
return null;
}
- /** Waits for the CPU cores and the broadcast queue to be idle. */
+ /** Waits for the broadcast queue and the CPU cores to be idle. */
public void waitCoolDownPeriod() {
- waitForCpuIdle();
waitForBroadcastIdle();
+ waitForCpuIdle();
}
private void waitForBroadcastIdle() {
- try {
- ShellHelper.runShellCommandWithTimeout(
- "am wait-for-broadcast-idle --flush-broadcast-loopers", TIMEOUT_IN_SECONDS);
- } catch (TimeoutException e) {
- Log.e(TAG, "Ending waitForBroadcastIdle because it didn't finish in "
- + TIMEOUT_IN_SECONDS + " seconds", e);
- }
+ Log.d(TAG, "starting to waitForBroadcastIdle");
+ final long startedAt = System.currentTimeMillis();
+ ShellHelper.runShellCommand("am wait-for-broadcast-idle --flush-broadcast-loopers");
+ final long elapsed = System.currentTimeMillis() - startedAt;
+ Log.d(TAG, "waitForBroadcastIdle is complete in " + elapsed + " ms");
}
-
private void waitForCpuIdle() {
- int count = 0;
- int idleCpuPercentage;
- while (count++ < TIMEOUT_IN_SECONDS) {
- idleCpuPercentage = getIdleCpuPercentage();
- Log.d(TAG, "Waiting for CPU idle #" + count + "=" + idleCpuPercentage + "%");
- if (idleCpuPercentage > CPU_IDLE_THRESHOLD_PERCENTAGE) {
+ Log.d(TAG, "starting to waitForCpuIdle");
+ final long startedAt = System.currentTimeMillis();
+ while (true) {
+ final int idleCpuPercentage = getIdleCpuPercentage();
+ final long elapsed = System.currentTimeMillis() - startedAt;
+ Log.d(TAG, "waitForCpuIdle " + idleCpuPercentage + "% (" + elapsed + "ms elapsed)");
+ if (idleCpuPercentage >= CPU_IDLE_THRESHOLD_PERCENTAGE) {
+ Log.d(TAG, "waitForCpuIdle is complete in " + elapsed + " ms");
+ return;
+ }
+ if (elapsed >= CPU_IDLE_TIMEOUT_MS) {
+ Log.e(TAG, "Ending waitForCpuIdle because it didn't finish in "
+ + CPU_IDLE_TIMEOUT_MS + " ms");
return;
}
SystemClock.sleep(1000);
}
- Log.e(TAG, "Ending waitForCpuIdle because it didn't finish in "
- + TIMEOUT_IN_SECONDS + " seconds");
}
private int getIdleCpuPercentage() {
String output = ShellHelper.runShellCommand("top -m 1 -n 1");
-
String[] tokens = output.split("\\s+");
-
float totalCpu = -1;
float idleCpu = -1;
for (String token : tokens) {
@@ -210,12 +211,10 @@
idleCpu = Float.parseFloat(token.split("%")[0]);
}
}
-
if (totalCpu < 0 || idleCpu < 0) {
Log.e(TAG, "Could not get idle cpu percentage, output=" + output);
return -1;
}
-
return (int) (100 * idleCpu / totalCpu);
}
}
\ No newline at end of file
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 76c1ed6..7dbf270 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -355,7 +355,7 @@
private static final String DEFAULT_FULL_BACKUP_AGENT = "android.app.backup.FullBackupAgent";
- private static final long BINDER_CALLBACK_THROTTLE = 10_100L;
+ private static final long BINDER_CALLBACK_THROTTLE_MS = 10_100L;
private long mBinderCallbackLast = -1;
/**
@@ -7551,12 +7551,13 @@
@Override
public void onTransactionError(int pid, int code, int flags, int err) {
final long now = SystemClock.uptimeMillis();
- if (now < mBinderCallbackLast + BINDER_CALLBACK_THROTTLE) {
+ if (now < mBinderCallbackLast + BINDER_CALLBACK_THROTTLE_MS) {
Slog.d(TAG, "Too many transaction errors, throttling freezer binder callback.");
return;
}
mBinderCallbackLast = now;
try {
+ Log.wtfStack(TAG, "Binder Transaction Error");
mgr.frozenBinderTransactionDetected(pid, code, flags, err);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f821520..4c839f1 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5637,6 +5637,10 @@
contentView.setDrawableTint(R.id.profile_badge, false,
getPrimaryTextColor(p), PorterDuff.Mode.SRC_ATOP);
}
+ contentView.setContentDescription(
+ R.id.profile_badge,
+ mContext.getSystemService(UserManager.class)
+ .getProfileAccessibilityString(mContext.getUserId()));
}
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index c529f7d..44444b5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5842,6 +5842,24 @@
* with {@link #PASSWORD_QUALITY_UNSPECIFIED} on that instance prior to setting complexity
* requirement for the managed profile.
*
+ * Starting from {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, after the password
+ * requirement has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+ * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+ * successfully set or not. This callback will contain:
+ * <ul>
+ * <li> The policy identifier {@link DevicePolicyIdentifiers#PASSWORD_COMPLEXITY_POLICY}
+ * <li> The {@link TargetUser} that this policy relates to
+ * <li> The {@link PolicyUpdateResult}, which will be
+ * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+ * reason the policy failed to be set
+ * e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+ * </ul>
+ * If there has been a change to the policy,
+ * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+ * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+ * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+ * will contain the reason why the policy changed.
+ *
* @throws SecurityException if the calling application is not a device owner or a profile
* owner.
* @throws IllegalArgumentException if the complexity level is not one of the four above.
@@ -5849,6 +5867,7 @@
* are password requirements specified using {@link #setPasswordQuality(ComponentName, int)}
* on the parent {@code DevicePolicyManager} instance.
*/
+ @SupportsCoexistence
@RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
public void setRequiredPasswordComplexity(@PasswordComplexity int passwordComplexity) {
if (mService == null) {
@@ -5880,6 +5899,7 @@
* owner.
*/
@PasswordComplexity
+ @SupportsCoexistence
@RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
public int getRequiredPasswordComplexity() {
if (mService == null) {
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 86b4180..7d5806a 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -328,6 +328,16 @@
}
flag {
+ name: "unmanaged_mode_migration"
+ namespace: "enterprise"
+ description: "Migrate APIs for unmanaged mode"
+ bug: "335624297"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "headless_single_user_fixes"
namespace: "enterprise"
description: "Various fixes for headless single user mode"
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 6ceae17..55c3bb60 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -166,4 +166,11 @@
namespace: "systemui"
description: "[Minimal HUN] Enables the compact heads up notification reply capability for Conversation Notifications"
bug: "336229954"
-}
\ No newline at end of file
+}
+
+flag {
+ name: "remove_remote_views"
+ namespace: "systemui"
+ description: "Removes all custom views"
+ bug: "342602960"
+}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2d9881a..9d2a8ee 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4398,7 +4398,6 @@
* Windows have title bars and can be moved and resized.
*/
// If this feature is present, you also need to set
- // com.android.internal.R.config_freeformWindowManagement to true in your configuration overlay.
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_FREEFORM_WINDOW_MANAGEMENT
= "android.software.freeform_window_management";
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a720b64..248ef1d 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2745,17 +2745,6 @@
ar.recycle();
Log.i(TAG, "...preloaded " + numberOfEntries + " resources in "
+ (SystemClock.uptimeMillis() - startTime) + "ms.");
-
- if (sysRes.getBoolean(
- com.android.internal.R.bool.config_freeformWindowManagement)) {
- startTime = SystemClock.uptimeMillis();
- ar = sysRes.obtainTypedArray(
- com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
- numberOfEntries = preloadDrawables(sysRes, ar);
- ar.recycle();
- Log.i(TAG, "...preloaded " + numberOfEntries + " resource in "
- + (SystemClock.uptimeMillis() - startTime) + "ms.");
- }
}
sysRes.finishPreloading();
} catch (RuntimeException e) {
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index ec67212..b2dcf90 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -739,6 +739,9 @@
* on is done.
*/
void onBlockingScreenOn(Runnable unblocker);
+
+ /** Whether auto brightness update in doze is allowed */
+ boolean allowAutoBrightnessInDoze();
}
/** A session token that associates a internal display with a {@link DisplayOffloader}. */
@@ -749,6 +752,9 @@
/** Whether the session is active. */
boolean isActive();
+ /** Whether auto brightness update in doze is allowed */
+ boolean allowAutoBrightnessInDoze();
+
/**
* Update the brightness from the offload chip.
* @param brightness The brightness value between {@link PowerManager.BRIGHTNESS_MIN} and
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index c611cb9..3e6223a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1948,6 +1948,10 @@
public static final int SETTLE_TO_ZERO_STATES = 0xffff0000 & ~MOST_INTERESTING_STATES;
+ // STATES bits that are used for Power Stats tracking
+ public static final int IMPORTANT_FOR_POWER_STATS_STATES =
+ STATE_GPS_ON_FLAG | STATE_SENSOR_ON_FLAG | STATE_AUDIO_ON_FLAG;
+
@UnsupportedAppUsage
public int states;
@@ -1988,6 +1992,10 @@
public static final int SETTLE_TO_ZERO_STATES2 = 0xffff0000 & ~MOST_INTERESTING_STATES2;
+ // STATES2 bits that are used for Power Stats tracking
+ public static final int IMPORTANT_FOR_POWER_STATS_STATES2 =
+ STATE2_VIDEO_ON_FLAG | STATE2_FLASHLIGHT_FLAG | STATE2_CAMERA_FLAG;
+
@UnsupportedAppUsage
public int states2;
@@ -2053,6 +2061,8 @@
public static final int EVENT_WAKEUP_AP = 0x0013;
// Event for reporting that a specific partial wake lock has been held for a long duration.
public static final int EVENT_LONG_WAKE_LOCK = 0x0014;
+ // Event for reporting change of some device states, triggered by a specific UID
+ public static final int EVENT_STATE_CHANGE = 0x0015;
// Number of event types.
public static final int EVENT_COUNT = 0x0016;
@@ -3066,13 +3076,13 @@
public static final String[] HISTORY_EVENT_NAMES = new String[] {
"null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
"active", "pkginst", "pkgunin", "alarm", "stats", "pkginactive", "pkgactive",
- "tmpwhitelist", "screenwake", "wakeupap", "longwake", "est_capacity"
+ "tmpwhitelist", "screenwake", "wakeupap", "longwake", "est_capacity", "state"
};
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
"Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
"Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw",
- "Esw", "Ewa", "Elw", "Eec"
+ "Esw", "Ewa", "Elw", "Eec", "Esc"
};
@FunctionalInterface
@@ -3087,7 +3097,7 @@
sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sIntToString,
sUidToString, sUidToString, sUidToString, sUidToString, sUidToString, sUidToString,
- sUidToString, sUidToString, sUidToString, sIntToString
+ sUidToString, sUidToString, sUidToString, sIntToString, sUidToString
};
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a409537..f357ebf 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1736,24 +1736,6 @@
"android.settings.NETWORK_OPERATOR_SETTINGS";
/**
- * Activity Action: Show settings for selecting the network provider.
- * <p>
- * In some cases, a matching Activity may not be provided, so ensure you
- * safeguard against this.
- * <p>
- * Access to this preference can be customized via Settings' app.
- * <p>
- * Input: Nothing.
- * <p>
- * Output: Nothing.
- *
- * @hide
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_NETWORK_PROVIDER_SETTINGS =
- "android.settings.NETWORK_PROVIDER_SETTINGS";
-
- /**
* Activity Action: Show settings for selection of 2G/3G.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/android/view/ContentRecordingSession.java b/core/java/android/view/ContentRecordingSession.java
index dc41b70..952c63b 100644
--- a/core/java/android/view/ContentRecordingSession.java
+++ b/core/java/android/view/ContentRecordingSession.java
@@ -58,6 +58,15 @@
/** Can't report (e.g. side loaded app). */
public static final int TARGET_UID_UNKNOWN = -2;
+ /** Task id is not set either because full screen capture or launching a new app */
+ public static final int TASK_ID_UNKNOWN = -1;
+
+ /**
+ * Id of Task that is launched to be captured for a single app capture session. The value may be
+ * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
+ */
+ private int mTaskId = TASK_ID_UNKNOWN;
+
/**
* Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
* recorded content rendered to its surface.
@@ -115,16 +124,16 @@
/** Returns an instance initialized for task recording. */
public static ContentRecordingSession createTaskSession(
@NonNull IBinder taskWindowContainerToken) {
- return createTaskSession(taskWindowContainerToken, TARGET_UID_UNKNOWN);
+ return createTaskSession(taskWindowContainerToken, TASK_ID_UNKNOWN);
}
/** Returns an instance initialized for task recording. */
public static ContentRecordingSession createTaskSession(
- @NonNull IBinder taskWindowContainerToken, int targetUid) {
+ @NonNull IBinder taskWindowContainerToken, int taskId) {
return new ContentRecordingSession()
.setContentToRecord(RECORD_CONTENT_TASK)
.setTokenToRecord(taskWindowContainerToken)
- .setTargetUid(targetUid);
+ .setTaskId(taskId);
}
/**
@@ -211,12 +220,14 @@
@DataClass.Generated.Member
/* package-private */ ContentRecordingSession(
+ int taskId,
int virtualDisplayId,
@RecordContent int contentToRecord,
int displayToRecord,
@Nullable IBinder tokenToRecord,
boolean waitingForConsent,
int targetUid) {
+ this.mTaskId = taskId;
this.mVirtualDisplayId = virtualDisplayId;
this.mContentToRecord = contentToRecord;
@@ -237,6 +248,15 @@
}
/**
+ * Id of Task that is launched to be captured for a single app capture session. The value may be
+ * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
+ */
+ @DataClass.Generated.Member
+ public int getTaskId() {
+ return mTaskId;
+ }
+
+ /**
* Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
* recorded content rendered to its surface.
*/
@@ -295,6 +315,16 @@
}
/**
+ * Id of Task that is launched to be captured for a single app capture session. The value may be
+ * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
+ */
+ @DataClass.Generated.Member
+ public @NonNull ContentRecordingSession setTaskId( int value) {
+ mTaskId = value;
+ return this;
+ }
+
+ /**
* Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
* recorded content rendered to its surface.
*/
@@ -374,6 +404,7 @@
// String fieldNameToString() { ... }
return "ContentRecordingSession { " +
+ "taskId = " + mTaskId + ", " +
"virtualDisplayId = " + mVirtualDisplayId + ", " +
"contentToRecord = " + recordContentToString(mContentToRecord) + ", " +
"displayToRecord = " + mDisplayToRecord + ", " +
@@ -396,6 +427,7 @@
ContentRecordingSession that = (ContentRecordingSession) o;
//noinspection PointlessBooleanExpression
return true
+ && mTaskId == that.mTaskId
&& mVirtualDisplayId == that.mVirtualDisplayId
&& mContentToRecord == that.mContentToRecord
&& mDisplayToRecord == that.mDisplayToRecord
@@ -411,6 +443,7 @@
// int fieldNameHashCode() { ... }
int _hash = 1;
+ _hash = 31 * _hash + mTaskId;
_hash = 31 * _hash + mVirtualDisplayId;
_hash = 31 * _hash + mContentToRecord;
_hash = 31 * _hash + mDisplayToRecord;
@@ -427,9 +460,10 @@
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
- if (mWaitingForConsent) flg |= 0x10;
- if (mTokenToRecord != null) flg |= 0x8;
+ if (mWaitingForConsent) flg |= 0x20;
+ if (mTokenToRecord != null) flg |= 0x10;
dest.writeByte(flg);
+ dest.writeInt(mTaskId);
dest.writeInt(mVirtualDisplayId);
dest.writeInt(mContentToRecord);
dest.writeInt(mDisplayToRecord);
@@ -449,13 +483,15 @@
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
- boolean waitingForConsent = (flg & 0x10) != 0;
+ boolean waitingForConsent = (flg & 0x20) != 0;
+ int taskId = in.readInt();
int virtualDisplayId = in.readInt();
int contentToRecord = in.readInt();
int displayToRecord = in.readInt();
- IBinder tokenToRecord = (flg & 0x8) == 0 ? null : (IBinder) in.readStrongBinder();
+ IBinder tokenToRecord = (flg & 0x10) == 0 ? null : (IBinder) in.readStrongBinder();
int targetUid = in.readInt();
+ this.mTaskId = taskId;
this.mVirtualDisplayId = virtualDisplayId;
this.mContentToRecord = contentToRecord;
@@ -496,6 +532,7 @@
@DataClass.Generated.Member
public static final class Builder {
+ private int mTaskId;
private int mVirtualDisplayId;
private @RecordContent int mContentToRecord;
private int mDisplayToRecord;
@@ -509,13 +546,25 @@
}
/**
+ * Id of Task that is launched to be captured for a single app capture session. The value may be
+ * {@link #TASK_ID_UNKNOWN} if the session is not for a single app capture.
+ */
+ @DataClass.Generated.Member
+ public @NonNull Builder setTaskId(int value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x1;
+ mTaskId = value;
+ return this;
+ }
+
+ /**
* Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
* recorded content rendered to its surface.
*/
@DataClass.Generated.Member
public @NonNull Builder setVirtualDisplayId(int value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x1;
+ mBuilderFieldsSet |= 0x2;
mVirtualDisplayId = value;
return this;
}
@@ -526,7 +575,7 @@
@DataClass.Generated.Member
public @NonNull Builder setContentToRecord(@RecordContent int value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x2;
+ mBuilderFieldsSet |= 0x4;
mContentToRecord = value;
return this;
}
@@ -540,7 +589,7 @@
@DataClass.Generated.Member
public @NonNull Builder setDisplayToRecord(int value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x4;
+ mBuilderFieldsSet |= 0x8;
mDisplayToRecord = value;
return this;
}
@@ -554,7 +603,7 @@
@DataClass.Generated.Member
public @NonNull Builder setTokenToRecord(@NonNull IBinder value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x8;
+ mBuilderFieldsSet |= 0x10;
mTokenToRecord = value;
return this;
}
@@ -568,7 +617,7 @@
@DataClass.Generated.Member
public @NonNull Builder setWaitingForConsent(boolean value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x10;
+ mBuilderFieldsSet |= 0x20;
mWaitingForConsent = value;
return this;
}
@@ -579,7 +628,7 @@
@DataClass.Generated.Member
public @NonNull Builder setTargetUid(int value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x20;
+ mBuilderFieldsSet |= 0x40;
mTargetUid = value;
return this;
}
@@ -587,27 +636,31 @@
/** Builds the instance. This builder should not be touched after calling this! */
public @NonNull ContentRecordingSession build() {
checkNotUsed();
- mBuilderFieldsSet |= 0x40; // Mark builder used
+ mBuilderFieldsSet |= 0x80; // Mark builder used
if ((mBuilderFieldsSet & 0x1) == 0) {
- mVirtualDisplayId = INVALID_DISPLAY;
+ mTaskId = TASK_ID_UNKNOWN;
}
if ((mBuilderFieldsSet & 0x2) == 0) {
- mContentToRecord = RECORD_CONTENT_DISPLAY;
+ mVirtualDisplayId = INVALID_DISPLAY;
}
if ((mBuilderFieldsSet & 0x4) == 0) {
- mDisplayToRecord = INVALID_DISPLAY;
+ mContentToRecord = RECORD_CONTENT_DISPLAY;
}
if ((mBuilderFieldsSet & 0x8) == 0) {
- mTokenToRecord = null;
+ mDisplayToRecord = INVALID_DISPLAY;
}
if ((mBuilderFieldsSet & 0x10) == 0) {
- mWaitingForConsent = false;
+ mTokenToRecord = null;
}
if ((mBuilderFieldsSet & 0x20) == 0) {
+ mWaitingForConsent = false;
+ }
+ if ((mBuilderFieldsSet & 0x40) == 0) {
mTargetUid = TARGET_UID_UNKNOWN;
}
ContentRecordingSession o = new ContentRecordingSession(
+ mTaskId,
mVirtualDisplayId,
mContentToRecord,
mDisplayToRecord,
@@ -618,7 +671,7 @@
}
private void checkNotUsed() {
- if ((mBuilderFieldsSet & 0x40) != 0) {
+ if ((mBuilderFieldsSet & 0x80) != 0) {
throw new IllegalStateException(
"This Builder should not be reused. Use a new Builder instance instead");
}
@@ -626,10 +679,10 @@
}
@DataClass.Generated(
- time = 1697456140720L,
+ time = 1716481148184L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/view/ContentRecordingSession.java",
- inputSignatures = "public static final int RECORD_CONTENT_DISPLAY\npublic static final int RECORD_CONTENT_TASK\npublic static final int TARGET_UID_FULL_SCREEN\npublic static final int TARGET_UID_UNKNOWN\nprivate int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate boolean mWaitingForConsent\nprivate int mTargetUid\npublic static android.view.ContentRecordingSession createDisplaySession(int)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder,int)\npublic static boolean isValid(android.view.ContentRecordingSession)\npublic static boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
+ inputSignatures = "public static final int RECORD_CONTENT_DISPLAY\npublic static final int RECORD_CONTENT_TASK\npublic static final int TARGET_UID_FULL_SCREEN\npublic static final int TARGET_UID_UNKNOWN\npublic static final int TASK_ID_UNKNOWN\nprivate int mTaskId\nprivate int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate boolean mWaitingForConsent\nprivate int mTargetUid\npublic static android.view.ContentRecordingSession createDisplaySession(int)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder,int)\npublic static boolean isValid(android.view.ContentRecordingSession)\npublic static boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
index 97f8084..9029685 100644
--- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java
+++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
@@ -68,6 +68,7 @@
mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT,
android.content.IntentSender.class);
String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ Log.i(TAG, "Unlaunchable activity for target package: " + targetPackageName);
final UserManager userManager = UserManager.get(this);
if (mUserId == UserHandle.USER_NULL) {
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index e6af64a..244165f 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -16,6 +16,10 @@
package com.android.internal.os;
+import static android.os.BatteryStats.HistoryItem.EVENT_FLAG_FINISH;
+import static android.os.BatteryStats.HistoryItem.EVENT_FLAG_START;
+import static android.os.BatteryStats.HistoryItem.EVENT_STATE_CHANGE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.BatteryConsumer;
@@ -1449,6 +1453,21 @@
}
/**
+ * Records an event when some state flag changes to true.
+ */
+ public void recordStateStartEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags,
+ int uid, String name) {
+ synchronized (this) {
+ mHistoryCur.states |= stateFlags;
+ mHistoryCur.eventCode = EVENT_STATE_CHANGE | EVENT_FLAG_START;
+ mHistoryCur.eventTag = mHistoryCur.localEventTag;
+ mHistoryCur.eventTag.uid = uid;
+ mHistoryCur.eventTag.string = name;
+ writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+ }
+ }
+
+ /**
* Records an event when some state flag changes to false.
*/
public void recordStateStopEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags) {
@@ -1459,6 +1478,21 @@
}
/**
+ * Records an event when some state flag changes to false.
+ */
+ public void recordStateStopEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags,
+ int uid, String name) {
+ synchronized (this) {
+ mHistoryCur.states &= ~stateFlags;
+ mHistoryCur.eventCode = EVENT_STATE_CHANGE | EVENT_FLAG_FINISH;
+ mHistoryCur.eventTag = mHistoryCur.localEventTag;
+ mHistoryCur.eventTag.uid = uid;
+ mHistoryCur.eventTag.string = name;
+ writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+ }
+ }
+
+ /**
* Records an event when some state flags change to true and some to false.
*/
public void recordStateChangeEvent(long elapsedRealtimeMs, long uptimeMs, int stateStartFlags,
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
deleted file mode 100644
index c6e8bf7..0000000
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (C) 2015 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.policy;
-
-import android.graphics.Insets;
-import android.graphics.RecordingCanvas;
-import android.graphics.Rect;
-import android.graphics.RenderNode;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Looper;
-import android.view.Choreographer;
-import android.view.ThreadedRenderer;
-
-/**
- * The thread which draws a fill in background while the app is resizing in areas where the app
- * content draw is lagging behind the resize operation.
- * It starts with the creation and it ends once someone calls destroy().
- * Any size changes can be passed by a call to setTargetRect will passed to the thread and
- * executed via the Choreographer.
- * @hide
- */
-public class BackdropFrameRenderer extends Thread implements Choreographer.FrameCallback {
-
- private DecorView mDecorView;
-
- // This is containing the last requested size by a resize command. Note that this size might
- // or might not have been applied to the output already.
- private final Rect mTargetRect = new Rect();
-
- // The render nodes for the multi threaded renderer.
- private ThreadedRenderer mRenderer;
- private RenderNode mFrameAndBackdropNode;
- private RenderNode mSystemBarBackgroundNode;
-
- private final Rect mOldTargetRect = new Rect();
- private final Rect mNewTargetRect = new Rect();
-
- private Choreographer mChoreographer;
-
- // Cached size values from the last render for the case that the view hierarchy is gone
- // during a configuration change.
- private int mLastContentWidth;
- private int mLastContentHeight;
- private int mLastXOffset;
- private int mLastYOffset;
-
- // Whether to report when next frame is drawn or not.
- private boolean mReportNextDraw;
-
- private Drawable mCaptionBackgroundDrawable;
- private Drawable mUserCaptionBackgroundDrawable;
- private Drawable mResizingBackgroundDrawable;
- private ColorDrawable mStatusBarColor;
- private ColorDrawable mNavigationBarColor;
- private boolean mOldFullscreen;
- private boolean mFullscreen;
- private final Rect mOldSystemBarInsets = new Rect();
- private final Rect mSystemBarInsets = new Rect();
- private final Rect mTmpRect = new Rect();
-
- public BackdropFrameRenderer(DecorView decorView, ThreadedRenderer renderer, Rect initialBounds,
- Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable,
- Drawable userCaptionBackgroundDrawable, int statusBarColor, int navigationBarColor,
- boolean fullscreen, Insets systemBarInsets) {
- setName("ResizeFrame");
-
- mRenderer = renderer;
- onResourcesLoaded(decorView, resizingBackgroundDrawable, captionBackgroundDrawable,
- userCaptionBackgroundDrawable, statusBarColor, navigationBarColor);
-
- // Create a render node for the content and frame backdrop
- // which can be resized independently from the content.
- mFrameAndBackdropNode = RenderNode.create("FrameAndBackdropNode", null);
-
- mRenderer.addRenderNode(mFrameAndBackdropNode, true);
-
- // Set the initial bounds and draw once so that we do not get a broken frame.
- mTargetRect.set(initialBounds);
- mFullscreen = fullscreen;
- mOldFullscreen = fullscreen;
- mSystemBarInsets.set(systemBarInsets.toRect());
- mOldSystemBarInsets.set(systemBarInsets.toRect());
-
- // Kick off our draw thread.
- start();
- }
-
- void onResourcesLoaded(DecorView decorView, Drawable resizingBackgroundDrawable,
- Drawable captionBackgroundDrawableDrawable, Drawable userCaptionBackgroundDrawable,
- int statusBarColor, int navigationBarColor) {
- synchronized (this) {
- mDecorView = decorView;
- mResizingBackgroundDrawable = resizingBackgroundDrawable != null
- && resizingBackgroundDrawable.getConstantState() != null
- ? resizingBackgroundDrawable.getConstantState().newDrawable()
- : null;
- mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable != null
- && captionBackgroundDrawableDrawable.getConstantState() != null
- ? captionBackgroundDrawableDrawable.getConstantState().newDrawable()
- : null;
- mUserCaptionBackgroundDrawable = userCaptionBackgroundDrawable != null
- && userCaptionBackgroundDrawable.getConstantState() != null
- ? userCaptionBackgroundDrawable.getConstantState().newDrawable()
- : null;
- if (mCaptionBackgroundDrawable == null) {
- mCaptionBackgroundDrawable = mResizingBackgroundDrawable;
- }
- if (statusBarColor != 0) {
- mStatusBarColor = new ColorDrawable(statusBarColor);
- addSystemBarNodeIfNeeded();
- } else {
- mStatusBarColor = null;
- }
- if (navigationBarColor != 0) {
- mNavigationBarColor = new ColorDrawable(navigationBarColor);
- addSystemBarNodeIfNeeded();
- } else {
- mNavigationBarColor = null;
- }
- }
- }
-
- private void addSystemBarNodeIfNeeded() {
- if (mSystemBarBackgroundNode != null) {
- return;
- }
- mSystemBarBackgroundNode = RenderNode.create("SystemBarBackgroundNode", null);
- mRenderer.addRenderNode(mSystemBarBackgroundNode, false);
- }
-
- /**
- * Call this function asynchronously when the window size has been changed or when the insets
- * have changed or whether window switched between a fullscreen or non-fullscreen layout.
- * The change will be picked up once per frame and the frame will be re-rendered accordingly.
- *
- * @param newTargetBounds The new target bounds.
- * @param fullscreen Whether the window is currently drawing in fullscreen.
- * @param systemBarInsets The current visible system insets for the window.
- */
- public void setTargetRect(Rect newTargetBounds, boolean fullscreen, Rect systemBarInsets) {
- synchronized (this) {
- mFullscreen = fullscreen;
- mTargetRect.set(newTargetBounds);
- mSystemBarInsets.set(systemBarInsets);
- // Notify of a bounds change.
- pingRenderLocked(false /* drawImmediate */);
- }
- }
-
- /**
- * The window got replaced due to a configuration change.
- */
- public void onConfigurationChange() {
- synchronized (this) {
- if (mRenderer != null) {
- // Enforce a window redraw.
- mOldTargetRect.set(0, 0, 0, 0);
- pingRenderLocked(false /* drawImmediate */);
- }
- }
- }
-
- /**
- * All resources of the renderer will be released. This function can be called from the
- * the UI thread as well as the renderer thread.
- */
- void releaseRenderer() {
- synchronized (this) {
- if (mRenderer != null) {
- // Invalidate the current content bounds.
- mRenderer.setContentDrawBounds(0, 0, 0, 0);
-
- // Remove the render node again
- // (see comment above - better to do that only once).
- mRenderer.removeRenderNode(mFrameAndBackdropNode);
- if (mSystemBarBackgroundNode != null) {
- mRenderer.removeRenderNode(mSystemBarBackgroundNode);
- }
-
- mRenderer = null;
-
- // Exit the renderer loop.
- pingRenderLocked(false /* drawImmediate */);
- }
- }
- }
-
- @Override
- public void run() {
- try {
- Looper.prepare();
- synchronized (this) {
- if (mRenderer == null) {
- // This can happen if 'releaseRenderer' is called immediately after 'start'.
- return;
- }
- mChoreographer = Choreographer.getInstance();
- }
- Looper.loop();
- } finally {
- releaseRenderer();
- }
- synchronized (this) {
- // Make sure no more messages are being sent.
- mChoreographer = null;
- Choreographer.releaseInstance();
- }
- }
-
- /**
- * The implementation of the FrameCallback.
- * @param frameTimeNanos The time in nanoseconds when the frame started being rendered,
- * in the {@link System#nanoTime()} timebase. Divide this value by {@code 1000000}
- */
- @Override
- public void doFrame(long frameTimeNanos) {
- synchronized (this) {
- if (mRenderer == null) {
- reportDrawIfNeeded();
- // Tell the looper to stop. We are done.
- Looper.myLooper().quit();
- return;
- }
- doFrameUncheckedLocked();
- }
- }
-
- private void doFrameUncheckedLocked() {
- mNewTargetRect.set(mTargetRect);
- if (!mNewTargetRect.equals(mOldTargetRect)
- || mOldFullscreen != mFullscreen
- || !mSystemBarInsets.equals(mOldSystemBarInsets)
- || mReportNextDraw) {
- mOldFullscreen = mFullscreen;
- mOldTargetRect.set(mNewTargetRect);
- mOldSystemBarInsets.set(mSystemBarInsets);
- redrawLocked(mNewTargetRect, mFullscreen);
- }
- }
-
- /**
- * The content is about to be drawn and we got the location of where it will be shown.
- * If a "redrawLocked" call has already been processed, we will re-issue the call
- * if the previous call was ignored since the size was unknown.
- * @param xOffset The x offset where the content is drawn to.
- * @param yOffset The y offset where the content is drawn to.
- * @param xSize The width size of the content. This should not be 0.
- * @param ySize The height of the content.
- * @return true if a frame should be requested after the content is drawn; false otherwise.
- */
- boolean onContentDrawn(int xOffset, int yOffset, int xSize, int ySize) {
- synchronized (this) {
- final boolean firstCall = mLastContentWidth == 0;
- // The current content buffer is drawn here.
- mLastContentWidth = xSize;
- mLastContentHeight = ySize;
- mLastXOffset = xOffset;
- mLastYOffset = yOffset;
-
- // Inform the renderer of the content's new bounds
- mRenderer.setContentDrawBounds(
- mLastXOffset,
- mLastYOffset,
- mLastXOffset + mLastContentWidth,
- mLastYOffset + mLastContentHeight);
-
- // If this was the first call and redrawLocked got already called prior
- // to us, we should re-issue a redrawLocked now.
- return firstCall;
- }
- }
-
- void onRequestDraw(boolean reportNextDraw) {
- synchronized (this) {
- mReportNextDraw = reportNextDraw;
- mOldTargetRect.set(0, 0, 0, 0);
- pingRenderLocked(true /* drawImmediate */);
- }
- }
-
- /**
- * Redraws the background, the caption and the system inset backgrounds if something changed.
- *
- * @param newBounds The window bounds which needs to be drawn.
- * @param fullscreen Whether the window is currently drawing in fullscreen.
- */
- private void redrawLocked(Rect newBounds, boolean fullscreen) {
-
- // Make sure that the other thread has already prepared the render draw calls for the
- // content. If any size is 0, we have to wait for it to be drawn first.
- if (mLastContentWidth == 0 || mLastContentHeight == 0) {
- return;
- }
-
- // Content may not be drawn at the surface origin, so we want to keep the offset when we're
- // resizing it.
- final int left = mLastXOffset + newBounds.left;
- final int top = mLastYOffset + newBounds.top;
- final int width = newBounds.width();
- final int height = newBounds.height();
-
- mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
-
- // Draw the caption and content backdrops in to our render node.
- RecordingCanvas canvas = mFrameAndBackdropNode.beginRecording(width, height);
- final Drawable drawable = mUserCaptionBackgroundDrawable != null
- ? mUserCaptionBackgroundDrawable : mCaptionBackgroundDrawable;
-
- if (drawable != null) {
- drawable.setBounds(0, 0, left + width, top);
- drawable.draw(canvas);
- }
-
- // The backdrop: clear everything with the background. Clipping is done elsewhere.
- if (mResizingBackgroundDrawable != null) {
- mResizingBackgroundDrawable.setBounds(0, 0, left + width, top + height);
- mResizingBackgroundDrawable.draw(canvas);
- }
- mFrameAndBackdropNode.endRecording();
-
- drawColorViews(left, top, width, height, fullscreen);
-
- // We need to render the node explicitly
- mRenderer.drawRenderNode(mFrameAndBackdropNode);
-
- reportDrawIfNeeded();
- }
-
- private void drawColorViews(int left, int top, int width, int height, boolean fullscreen) {
- if (mSystemBarBackgroundNode == null) {
- return;
- }
- RecordingCanvas canvas = mSystemBarBackgroundNode.beginRecording(width, height);
- mSystemBarBackgroundNode.setLeftTopRightBottom(left, top, left + width, top + height);
- final int topInset = mSystemBarInsets.top;
- if (mStatusBarColor != null) {
- mStatusBarColor.setBounds(0, 0, left + width, topInset);
- mStatusBarColor.draw(canvas);
- }
-
- // We only want to draw the navigation bar if our window is currently fullscreen because we
- // don't want the navigation bar background be moving around when resizing in docked mode.
- // However, we need it for the transitions into/out of docked mode.
- if (mNavigationBarColor != null && fullscreen) {
- DecorView.getNavigationBarRect(width, height, mSystemBarInsets, mTmpRect, 1f);
- mNavigationBarColor.setBounds(mTmpRect);
- mNavigationBarColor.draw(canvas);
- }
- mSystemBarBackgroundNode.endRecording();
- mRenderer.drawRenderNode(mSystemBarBackgroundNode);
- }
-
- /** Notify view root that a frame has been drawn by us, if it has requested so. */
- private void reportDrawIfNeeded() {
- if (mReportNextDraw) {
- if (mDecorView.isAttachedToWindow()) {
- mDecorView.getViewRootImpl().reportDrawFinish();
- }
- mReportNextDraw = false;
- }
- }
-
- /**
- * Sends a message to the renderer to wake up and perform the next action which can be
- * either the next rendering or the self destruction if mRenderer is null.
- * Note: This call must be synchronized.
- *
- * @param drawImmediate if we should draw immediately instead of scheduling a frame
- */
- private void pingRenderLocked(boolean drawImmediate) {
- if (mChoreographer != null && !drawImmediate) {
- mChoreographer.postFrameCallback(this);
- } else {
- doFrameUncheckedLocked();
- }
- }
-
- void setUserCaptionBackgroundDrawable(Drawable userCaptionBackgroundDrawable) {
- synchronized (this) {
- mUserCaptionBackgroundDrawable = userCaptionBackgroundDrawable;
- }
- }
-}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 74c2325..55c6ad1 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -57,7 +57,6 @@
import android.graphics.PixelFormat;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
-import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
@@ -238,11 +237,8 @@
private Rect mTempRect;
private boolean mWindowResizeCallbacksAdded = false;
- private Drawable.Callback mLastBackgroundDrawableCb = null;
- private BackdropFrameRenderer mBackdropFrameRenderer = null;
private Drawable mOriginalBackgroundDrawable;
private Drawable mLastOriginalBackgroundDrawable;
- private Drawable mResizingBackgroundDrawable;
private BackgroundBlurDrawable mBackgroundBlurDrawable;
private BackgroundBlurDrawable mLastBackgroundBlurDrawable;
@@ -253,8 +249,6 @@
*/
@Nullable
private Drawable mPendingWindowBackground;
- private Drawable mCaptionBackgroundDrawable;
- private Drawable mUserCaptionBackgroundDrawable;
String mLogTag = TAG;
private final Rect mFloatingInsets = new Rect();
@@ -329,26 +323,6 @@
}
@Override
- public boolean gatherTransparentRegion(Region region) {
- boolean statusOpaque = gatherTransparentRegion(mStatusColorViewState, region);
- boolean navOpaque = gatherTransparentRegion(mNavigationColorViewState, region);
- boolean decorOpaque = super.gatherTransparentRegion(region);
-
- // combine bools after computation, so each method above always executes
- return statusOpaque || navOpaque || decorOpaque;
- }
-
- boolean gatherTransparentRegion(ColorViewState colorViewState, Region region) {
- if (colorViewState.view != null && colorViewState.visible && isResizing()) {
- // If a visible ColorViewState is in a resizing host DecorView, forcibly register its
- // opaque area, since it's drawn by a different root RenderNode. It would otherwise be
- // rejected by ViewGroup#gatherTransparentRegion() for the view not being VISIBLE.
- return colorViewState.view.gatherTransparentRegion(region);
- }
- return false; // no opaque area added
- }
-
- @Override
public void onDraw(Canvas c) {
super.onDraw(c);
@@ -977,15 +951,11 @@
updateColorViews(null /* insets */, false /* animate */);
}
if (drawable != null) {
- mResizingBackgroundDrawable = enforceNonTranslucentBackground(drawable,
- mWindow.isTranslucent() || mWindow.isShowingWallpaper());
- } else {
- mResizingBackgroundDrawable = getResizingBackgroundDrawable(
- mWindow.mBackgroundDrawable, mWindow.mBackgroundFallbackDrawable,
- mWindow.isTranslucent() || mWindow.isShowingWallpaper());
- }
- if (mResizingBackgroundDrawable != null) {
- mResizingBackgroundDrawable.getPadding(mBackgroundPadding);
+ drawable.getPadding(mBackgroundPadding);
+ } else if (mWindow.mBackgroundDrawable != null) {
+ mWindow.mBackgroundDrawable.getPadding(mBackgroundPadding);
+ } else if (mWindow.mBackgroundFallbackDrawable != null) {
+ mWindow.mBackgroundFallbackDrawable.getPadding(mBackgroundPadding);
} else {
mBackgroundPadding.setEmpty();
}
@@ -1451,7 +1421,7 @@
mWindow.getAttributes().flags, force);
boolean show = state.attributes.isVisible(state.present, color,
mWindow.getAttributes().flags, force);
- boolean showView = show && !isResizing() && size > 0;
+ boolean showView = show && size > 0;
boolean visibilityChanged = false;
View view = state.view;
@@ -1505,7 +1475,7 @@
}
if (visibilityChanged) {
view.animate().cancel();
- if (animate && !isResizing()) {
+ if (animate) {
if (showView) {
if (view.getVisibility() != VISIBLE) {
view.setVisibility(VISIBLE);
@@ -1834,10 +1804,6 @@
// Note that our ViewRootImpl object will not change.
getViewRootImpl().addWindowCallbacks(this);
mWindowResizeCallbacksAdded = true;
- } else if (mBackdropFrameRenderer != null) {
- // We are resizing and this call happened due to a configuration change. Tell the
- // renderer about it.
- mBackdropFrameRenderer.onConfigurationChange();
}
updateBackgroundBlurRadius();
@@ -1877,8 +1843,6 @@
st.menu.close();
}
- releaseThreadedRenderer();
-
if (mWindowResizeCallbacksAdded) {
getViewRootImpl().removeWindowCallbacks(this);
mWindowResizeCallbacksAdded = false;
@@ -2158,14 +2122,6 @@
}
void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
- if (mBackdropFrameRenderer != null) {
- loadBackgroundDrawablesIfNeeded();
- mBackdropFrameRenderer.onResourcesLoaded(
- this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
- mUserCaptionBackgroundDrawable, getCurrentColor(mStatusColorViewState),
- getCurrentColor(mNavigationColorViewState));
- }
-
final View root = inflater.inflate(layoutResource, null);
// Put it below the color views.
@@ -2174,63 +2130,6 @@
initializeElevation();
}
- private void loadBackgroundDrawablesIfNeeded() {
- if (mResizingBackgroundDrawable == null) {
- mResizingBackgroundDrawable = getResizingBackgroundDrawable(mWindow.mBackgroundDrawable,
- mWindow.mBackgroundFallbackDrawable, mWindow.isTranslucent()
- || mWindow.isShowingWallpaper());
- if (mResizingBackgroundDrawable == null) {
- // We shouldn't really get here as the background fallback should be always
- // available since it is defaulted by the system.
- Log.w(mLogTag, "Failed to find background drawable for PhoneWindow=" + mWindow);
- }
- }
- if (mCaptionBackgroundDrawable == null) {
- mCaptionBackgroundDrawable = getContext().getDrawable(
- R.drawable.decor_caption_title_focused);
- }
- if (mResizingBackgroundDrawable != null) {
- mLastBackgroundDrawableCb = mResizingBackgroundDrawable.getCallback();
- mResizingBackgroundDrawable.setCallback(null);
- }
- }
-
- /**
- * Returns the color used to fill areas the app has not rendered content to yet when the
- * user is resizing the window of an activity in multi-window mode.
- */
- public static Drawable getResizingBackgroundDrawable(@Nullable Drawable backgroundDrawable,
- @Nullable Drawable fallbackDrawable, boolean windowTranslucent) {
- if (backgroundDrawable != null) {
- return enforceNonTranslucentBackground(backgroundDrawable, windowTranslucent);
- }
-
- if (fallbackDrawable != null) {
- return enforceNonTranslucentBackground(fallbackDrawable, windowTranslucent);
- }
- return new ColorDrawable(Color.BLACK);
- }
-
- /**
- * Enforces a drawable to be non-translucent to act as a background if needed, i.e. if the
- * window is not translucent.
- */
- private static Drawable enforceNonTranslucentBackground(Drawable drawable,
- boolean windowTranslucent) {
- if (!windowTranslucent && drawable instanceof ColorDrawable) {
- ColorDrawable colorDrawable = (ColorDrawable) drawable;
- int color = colorDrawable.getColor();
- if (Color.alpha(color) != 255) {
- ColorDrawable copy = (ColorDrawable) colorDrawable.getConstantState().newDrawable()
- .mutate();
- copy.setColor(
- Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
- return copy;
- }
- }
- return drawable;
- }
-
void clearContentView() {
for (int i = getChildCount() - 1; i >= 0; i--) {
View v = getChildAt(i);
@@ -2243,21 +2142,13 @@
@Override
public void onWindowSizeIsChanging(Rect newBounds, boolean fullscreen, Rect systemInsets,
- Rect stableInsets) {
- if (mBackdropFrameRenderer != null) {
- mBackdropFrameRenderer.setTargetRect(newBounds, fullscreen, systemInsets);
- }
- }
+ Rect stableInsets) {}
@Override
public void onWindowDragResizeStart(Rect initialBounds, boolean fullscreen, Rect systemInsets,
Rect stableInsets) {
if (mWindow.isDestroyed()) {
// If the owner's window is gone, we should not be able to come here anymore.
- releaseThreadedRenderer();
- return;
- }
- if (mBackdropFrameRenderer != null) {
return;
}
getViewRootImpl().requestInvalidateRootRenderNode();
@@ -2265,28 +2156,23 @@
@Override
public void onWindowDragResizeEnd() {
- releaseThreadedRenderer();
updateColorViews(null /* insets */, false);
getViewRootImpl().requestInvalidateRootRenderNode();
}
@Override
public boolean onContentDrawn(int offsetX, int offsetY, int sizeX, int sizeY) {
- if (mBackdropFrameRenderer == null) {
- return false;
- }
- return mBackdropFrameRenderer.onContentDrawn(offsetX, offsetY, sizeX, sizeY);
+ return false;
}
@Override
public void onRequestDraw(boolean reportNextDraw) {
- if (mBackdropFrameRenderer != null) {
- mBackdropFrameRenderer.onRequestDraw(reportNextDraw);
- } else if (reportNextDraw) {
- // If render thread is gone, just report immediately.
- if (isAttachedToWindow()) {
- getViewRootImpl().reportDrawFinish();
- }
+ if (!reportNextDraw) {
+ return;
+ }
+ // If render thread is gone, just report immediately.
+ if (isAttachedToWindow()) {
+ getViewRootImpl().reportDrawFinish();
}
}
@@ -2307,25 +2193,6 @@
mLegacyNavigationBarBackgroundPaint);
}
- /** Release the renderer thread which is usually done when the user stops resizing. */
- private void releaseThreadedRenderer() {
- if (mResizingBackgroundDrawable != null && mLastBackgroundDrawableCb != null) {
- mResizingBackgroundDrawable.setCallback(mLastBackgroundDrawableCb);
- mLastBackgroundDrawableCb = null;
- }
-
- if (mBackdropFrameRenderer != null) {
- mBackdropFrameRenderer.releaseRenderer();
- mBackdropFrameRenderer = null;
- // Bring the shadow back.
- updateElevation();
- }
- }
-
- private boolean isResizing() {
- return mBackdropFrameRenderer != null;
- }
-
/**
* The elevation gets set for the first time and the framework needs to be informed that
* the surface layer gets created with the shadow size in mind.
@@ -2348,7 +2215,7 @@
final boolean wasAdjustedForStack = mElevationAdjustedForStack;
// Do not use a shadow when we are in resizing mode (mBackdropFrameRenderer not null)
// since the shadow is bound to the content size and not the target size.
- if ((windowingMode == WINDOWING_MODE_FREEFORM) && !isResizing()) {
+ if (windowingMode == WINDOWING_MODE_FREEFORM) {
elevation = hasWindowFocus() ?
DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
// Add a maximum shadow height value to the top level view.
@@ -2367,16 +2234,8 @@
// Don't change the elevation if we didn't previously adjust it for the stack it was in
// or it didn't change.
- if ((wasAdjustedForStack || mElevationAdjustedForStack)
- && getElevation() != elevation) {
- if (!isResizing()) {
- mWindow.setElevation(elevation);
- } else {
- // Just suppress the shadow when resizing, don't adjust surface insets because it'll
- // cause a flicker when drag resize for freeform window starts. #onContentDrawn()
- // will compensate the offset when passing to BackdropFrameRenderer.
- setElevation(elevation);
- }
+ if ((wasAdjustedForStack || mElevationAdjustedForStack) && getElevation() != elevation) {
+ mWindow.setElevation(elevation);
}
}
@@ -2390,16 +2249,6 @@
getResources().getDisplayMetrics());
}
- /**
- * Provide an override of the caption background drawable.
- */
- void setUserCaptionBackgroundDrawable(Drawable drawable) {
- mUserCaptionBackgroundDrawable = drawable;
- if (mBackdropFrameRenderer != null) {
- mBackdropFrameRenderer.setUserCaptionBackgroundDrawable(drawable);
- }
- }
-
private static String getTitleSuffix(WindowManager.LayoutParams params) {
if (params == null) {
return "";
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index a091e19..2194c89 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -4055,7 +4055,8 @@
@Override
public void setResizingCaptionDrawable(Drawable drawable) {
- mDecor.setUserCaptionBackgroundDrawable(drawable);
+ // TODO(b/333724879): Deprecate this public API. The new caption in WM shell allows the app
+ // content to draw behind it directly if requested.
}
@Override
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 2068bd7..3006e20 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -1411,8 +1411,10 @@
return JNI_TRUE;
}
- env->CallStaticVoidMethod(gBinderOffsets.mClass, gBinderOffsets.mTransactionCallback, getpid(),
- code, flags, err);
+ if (err == FAILED_TRANSACTION) {
+ env->CallStaticVoidMethod(gBinderOffsets.mClass, gBinderOffsets.mTransactionCallback,
+ getpid(), code, flags, err);
+ }
if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
diff --git a/core/res/res/drawable/decor_caption_title.xml b/core/res/res/drawable/decor_caption_title.xml
deleted file mode 100644
index 591605d3..0000000
--- a/core/res/res/drawable/decor_caption_title.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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">
- <item android:state_window_focused="true"
- android:drawable="@drawable/decor_caption_title_focused" />
- <item android:drawable="@drawable/decor_caption_title_unfocused" />
-</selector>
diff --git a/core/res/res/drawable/decor_caption_title_focused.xml b/core/res/res/drawable/decor_caption_title_focused.xml
deleted file mode 100644
index 7d1c230..0000000
--- a/core/res/res/drawable/decor_caption_title_focused.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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 android:shape="rectangle"
- android:tintMode="multiply"
- android:tint="#D8D8D8"
- xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Fading the primary color to 85% blackness -->
- <solid android:color="?android:attr/colorPrimary" />
-</shape>
diff --git a/core/res/res/drawable/decor_caption_title_unfocused.xml b/core/res/res/drawable/decor_caption_title_unfocused.xml
deleted file mode 100644
index 2846d8ca..0000000
--- a/core/res/res/drawable/decor_caption_title_unfocused.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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 android:shape="rectangle"
- android:tintMode="multiply"
- android:tint="#F2F2F2"
- xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Fading the primary color to 95% blackness -->
- <solid android:color="?android:attr/colorPrimary"/>
-</shape>
diff --git a/core/res/res/drawable/decor_close_button_dark.xml b/core/res/res/drawable/decor_close_button_dark.xml
deleted file mode 100644
index 950e4fd..0000000
--- a/core/res/res/drawable/decor_close_button_dark.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-Copyright (C) 2015 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
- android:tint="@color/decor_button_dark_color"
- >
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="8.0"
- android:translateY="8.0" >
- <path
- android:fillColor="@color/white"
- android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
- </group>
-</vector>
diff --git a/core/res/res/drawable/decor_close_button_light.xml b/core/res/res/drawable/decor_close_button_light.xml
deleted file mode 100644
index d75cd25..0000000
--- a/core/res/res/drawable/decor_close_button_light.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-Copyright (C) 2015 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
- android:tint="@color/decor_button_light_color"
- >
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="8.0"
- android:translateY="8.0" >
- <path
- android:fillColor="@color/white"
- android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
- </group>
-</vector>
diff --git a/core/res/res/drawable/decor_maximize_button_dark.xml b/core/res/res/drawable/decor_maximize_button_dark.xml
deleted file mode 100644
index 619b460..0000000
--- a/core/res/res/drawable/decor_maximize_button_dark.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
- android:tint="@color/decor_button_dark_color"
- >
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="8.0"
- android:translateY="8.0" >
- <path
- android:fillColor="@color/white"
- android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
- <path
- android:fillColor="@color/white"
- android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
- </group>
-</vector>
-
-
diff --git a/core/res/res/drawable/decor_maximize_button_light.xml b/core/res/res/drawable/decor_maximize_button_light.xml
deleted file mode 100644
index 5b55fd2..0000000
--- a/core/res/res/drawable/decor_maximize_button_light.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
-Copyright (C) 2015 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.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0"
- android:tint="@color/decor_button_light_color"
- >
- <group android:scaleX="0.5"
- android:scaleY="0.5"
- android:translateX="8.0"
- android:translateY="8.0" >
- <path
- android:fillColor="@color/white"
- android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
- <path
- android:fillColor="@color/white"
- android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
- </group>
-</vector>
diff --git a/core/res/res/layout/decor_caption.xml b/core/res/res/layout/decor_caption.xml
deleted file mode 100644
index 0246736..0000000
--- a/core/res/res/layout/decor_caption.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2015, 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.internal.widget.DecorCaptionView xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:descendantFocusability="beforeDescendants" >
- <LinearLayout
- android:id="@+id/caption"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="end"
- android:background="@drawable/decor_caption_title"
- android:focusable="false"
- android:descendantFocusability="blocksDescendants" >
- <Button
- android:id="@+id/maximize_window"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_margin="5dp"
- android:padding="4dp"
- android:layout_gravity="center_vertical|end"
- android:contentDescription="@string/maximize_button_text"
- android:background="@drawable/decor_maximize_button_dark" />
- <Button
- android:id="@+id/close_window"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_margin="5dp"
- android:padding="4dp"
- android:layout_gravity="center_vertical|end"
- android:contentDescription="@string/close_button_text"
- android:background="@drawable/decor_close_button_dark" />
- </LinearLayout>
-</com.android.internal.widget.DecorCaptionView>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7fe8641..b532ad7 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jou werkprofiel is nie meer op hierdie toestel beskikbaar nie"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Te veel wagwoordpogings"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrateur het toestel vir persoonlike gebruik afgestaan"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Toestel word bestuur"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Jou organisasie bestuur hierdie toestel en kan netwerkverkeer monitor. Tik vir besonderhede."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Programme kan toegang tot jou ligging kry"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Stembystand"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Snelsluit"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Antwoord"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nuwe kennisgewing"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fisieke sleutelbord"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sekuriteit"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Stel Gesigslot weer op"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 1d1ded6..060c8cb 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"የሥራ መገለጫዎ ከዚህ በኋላ በዚህ መሣሪያ ላይ አይገኝም"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"በጣም ብዙ የይለፍ ቃል ሙከራዎች"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"አስተዳዳሪ መሣሪያዎን ለግል ጥቅም ትተውታል"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"መሣሪያው የሚተዳደር ነው"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"የእርስዎ ድርጅት ይህን መሣሪያ ያስተዳድራል፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል። ዝርዝሮችን ለማግኘት መታ ያድርጉ።"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"መተግበሪያዎች የእርስዎን አካባቢ መድረስ ይችላሉ"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"የድምጽ እርዳታ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"መቆለፊያ"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"መልስ"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"አዲስ ማሳወቂያ"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"አካላዊ ቁልፍ ሰሌዳ"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ደህንነት"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"በመልክ መክፈትን እንደገና ያዋቅሩ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3a4a79a..f59a8cb 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -205,6 +205,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"لم يعد ملفك الشخصي للعمل متاحًا على هذا الجهاز"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"تم إجراء محاولات كثيرة جدًا لإدخال كلمة المرور"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"تنازل المشرف عن الجهاز للاستخدام الشخصي"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"تتم إدارة الجهاز"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"تدير مؤسستك هذا الجهاز ويمكنها مراقبة حركة بيانات الشبكة. يمكنك النقر للحصول على تفاصيل."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"يمكن للتطبيقات الوصول إلى موقعك الجغرافي"</string>
@@ -2419,10 +2423,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"إعادة إعداد ميزة \"فتح الجهاز بالتعرّف على الوجه\""</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index e8346b7..c20d5ae 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল এই ডিভাইচটোত আৰু উপলব্ধ নহয়"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"বহুতবাৰ ভুলকৈ পাছৱৰ্ড দিয়া হৈছে"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"প্ৰশাসকে ডিভাইচটো ব্যক্তিগত ব্যৱহাৰৰ বাবে বাজেয়প্ত কৰিছে"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"পৰিচালিত ডিভাইচ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"আপোনাৰ প্ৰতিষ্ঠানটোৱে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে। সবিশেষ জানিবলৈ টিপক।"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"এপ্সমূহে আপোনাৰ অৱস্থান এক্সেছ কৰিব পাৰে"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ফে’চ আনলক পুনৰ ছেট আপ কৰক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 5f9e9fa..9d44759 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"İş profili artıq bu cihazda əlçatan deyil"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Həddindən çox parol cəhdi"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin şəxsi istifadə üçün cihazdan imtina etdi"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Şəxsi sahə silindi"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Təşkilat bu idarə olunan cihazda şəxsi sahələrə icazə vermir."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz idarə olunur"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Təşkilat bu cihazı idarə edir və şəbəkənin ötürülməsinə nəzarət edə bilər. Detallar üçün klikləyin."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Tətbiqlər məkanınıza daxil ola bilər"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Üzlə Kilidaçmanı yenidən ayarlayın"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index db9a93f..140ca4a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Poslovni profil više nije dostupan na ovom uređaju"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa lozinke"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacije mogu da pristupaju vašoj lokaciji"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zaključavanje"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Odgovori"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Novo obaveštenje"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizička tastatura"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Bezbednost"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo podesite otključavanje licem"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index ec19c2d..116a836 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -203,6 +203,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ваш працоўны профіль больш не даступны на гэтай прыладзе"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Занадта шмат спроб уводу пароля"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Адміністратар пераналадзіў прыладу для асабістага выкарыстання"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Прылада знаходзіцца пад кіраваннем"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Праграмы могуць атрымліваць даныя пра ваша месцазнаходжанне"</string>
@@ -285,8 +289,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Галас. дапамога"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Блакіроўка"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Адказаць"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Новае апавяшчэнне"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Фізічная клавіятура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Бяспека"</string>
@@ -2418,10 +2421,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Паўторна наладзьце распазнаванне твару"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 1b73710..086cb63 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Служебният ви потребителски профил вече не е налице на това устройство"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Опитите за паролата са твърде много"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Администраторът предостави устройствотото за лична употреба"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Устройството се управлява"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Организацията ви управлява това устройство и може да наблюдава мрежовия трафик. Докоснете за подробности."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Прилож. имат достъп до местоположението ви"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Гласова помощ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Заключване"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Отговор"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Ново известие"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физическа клавиатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Сигурност"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Повторно настройване на „Отключване с лице“"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 0e32bbe6..679cf57 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"আপনার কর্মস্থলের প্রোফাইলটি আর এই ডিভাইসে নেই"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"বহুবার ভুল পাসওয়ার্ড দিয়েছেন"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ব্যক্তিগত কাজের জন্য অ্যাডমিন এই ডিভাইস ব্যবহার করার অনুমতি দেয়নি"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"ডিভাইসটি পরিচালনা করা হচ্ছে"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে। বিশদ বিবরণের জন্য ট্যাপ করুন।,"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"অ্যাপগুলি আপনার লোকেশন অ্যাক্সেস করতে পারবে"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ভয়েস সহায়তা"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"লকডাউন"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"৯৯৯+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"উত্তর দিন"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"নতুন বিজ্ঞপ্তি"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ফিজিক্যাল কীবোর্ড"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"নিরাপত্তা"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"\'ফেস আনলক\' আবার সেট-আপ করুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 63a83f0..a4d1b46 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Radni profil više nije dostupan na ovom uređaju"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše puta ste pokušali otključati uređaj"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja."</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacije mogu pristupiti vašoj lokaciji"</string>
@@ -2416,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo postavite otključavanje licem"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 1fd814d..3219c56 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"El teu perfil de treball ja no està disponible en aquest dispositiu"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Has intentat introduir la contrasenya massa vegades"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrador ha cedit el dispositiu per a ús personal"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"El dispositiu està gestionat"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"La teva organització gestiona aquest dispositiu i és possible que supervisi el trànsit de xarxa. Toca per obtenir més informació."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Les aplicacions poden accedir a la teva ubicació"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Assist. per veu"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueig de seguretat"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"+999"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Respon"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificació nova"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclat físic"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguretat"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Torna a configurar Desbloqueig facial"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index be4128f..2305f6a 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -203,6 +203,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Váš pracovní profil v tomto zařízení již není k dispozici"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Příliš mnoho pokusů o zadání hesla"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrátor zařízení uvolnil k osobnímu používání"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Zařízení je spravováno"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Toto zařízení je spravováno vaší organizací, která může sledovat síťový provoz. Podrobnosti zobrazíte klepnutím."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikace mají přístup k vaší poloze"</string>
@@ -1636,7 +1640,7 @@
<string name="issued_by" msgid="7872459822431585684">"Vydal:"</string>
<string name="validity_period" msgid="1717724283033175968">"Platnost:"</string>
<string name="issued_on" msgid="5855489688152497307">"Datum vydání:"</string>
- <string name="expires_on" msgid="1623640879705103121">"Platnost vyprší:"</string>
+ <string name="expires_on" msgid="1623640879705103121">"Platnost skončí:"</string>
<string name="serial_number" msgid="3479576915806623429">"Sériové číslo:"</string>
<string name="fingerprints" msgid="148690767172613723">"Digitální otisky:"</string>
<string name="sha256_fingerprint" msgid="7103976380961964600">"Digitální otisk SHA-256"</string>
@@ -2417,10 +2421,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Nastavte odemknutí obličejem znovu"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9b2844b..dd50635 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Din arbejdsprofil er ikke længere tilgængelig på denne enhed"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"For mange mislykkede adgangskodeforsøg"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratoren har gjort personlig brug af enheden utilgængelig"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Det private område er fjernet"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Din organisation tillader ikke private områder på denne administrerede enhed."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Dette er en administreret enhed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik. Tryk for at se info."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps kan få adgang til din lokation"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansigtsoplåsning igen"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 1df8954..af5a20d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Dein Arbeitsprofil ist auf diesem Gerät nicht mehr verfügbar"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zu viele falsche Passworteingaben"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator hat das Gerät zur persönlichen Nutzung abgegeben"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Dies ist ein verwaltetes Gerät"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Deine Organisation verwaltet dieses Gerät und überprüft unter Umständen den Netzwerkverkehr. Tippe hier, um weitere Informationen zu erhalten."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps können auf deinen Standort zugreifen"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Sprachassistent"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Sperren"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Antworten"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Neue Benachrichtigung"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Physische Tastatur"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sicherheit"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Entsperrung per Gesichtserkennung neu einrichten"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 3c7d167..31a52c8 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Το προφίλ εργασίας σας δεν είναι πια διαθέσιμο σε αυτήν τη συσκευή"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Πάρα πολλές προσπάθειες εισαγωγής κωδικού πρόσβασης"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Συσκευή από την οποία αποσύρθηκε ο διαχειριστής για προσωπική χρήση"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Η συσκευή είναι διαχειριζόμενη"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ο οργανισμός σας διαχειρίζεται αυτήν τη συσκευή και ενδέχεται να παρακολουθεί την επισκεψιμότητα δικτύου. Πατήστε για λεπτομέρειες."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Οι εφαρμογές μπορούν να αποκτήσουν πρόσβαση στην τοποθεσία σας"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Φων.υποβοηθ."</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Κλείδωμα"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Απάντηση"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Νέα ειδοποίηση"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Κανονικό πληκτρολόγιο"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Ασφάλεια"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με το πρόσωπο"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 0c782a7..a051155 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Private space removed"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Your organisation does not allow private spaces on this managed device."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps can access your location"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index d1894b5..8f3f623 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Private space removed"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Your organisation does not allow private spaces on this managed device."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organization manages this device and may monitor network traffic. Tap for details."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps can access your location"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 632585f..ff3c20a 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Private space removed"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Your organisation does not allow private spaces on this managed device."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps can access your location"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 1c55884..daa61ab 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Private space removed"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Your organisation does not allow private spaces on this managed device."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps can access your location"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index e08f934..98cac20 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Private space removed"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Your organisation does not allow private spaces on this managed device."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organization manages this device and may monitor network traffic. Tap for details."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps can access your location"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 30a0457..98a2c50 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Tu perfil de trabajo ya no está disponible en este dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiados intentos para ingresar la contraseña"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"El administrador no permite hacer un uso personal del dispositivo"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Dispositivo administrado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y es posible que controle el tráfico de red. Presiona para obtener más información."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Las apps pueden acceder a tu ubicación"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Responder"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificación nueva"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguridad"</string>
@@ -1190,8 +1193,8 @@
<string name="deleteText" msgid="4200807474529938112">"Eliminar"</string>
<string name="inputMethod" msgid="1784759500516314751">"Método de entrada"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Acciones de texto"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"La función Escritura a mano no es compatible en este campo"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"La función Escritura a mano no es compatible en los campos de contraseñas"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"La función Escritura a mano no está disponible en este campo"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"La Escritura a mano no está disponible en campos de contraseñas"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Atrás"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Cambiar método de entrada"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"Queda poco espacio de almacenamiento"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vuelve a configurar el Desbloqueo facial"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 5079fdf..2e23042 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Tu perfil de trabajo ya no está disponible en este dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Has fallado demasiadas veces al introducir la contraseña"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"El administrador no permite hacer un uso personal del dispositivo"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"El dispositivo está administrado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y puede supervisar el tráfico de red. Toca la notificación para obtener más información."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Las aplicaciones pueden acceder a tu ubicación"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo de seguridad"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"> 999"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Responder"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificación nueva"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguridad"</string>
@@ -1190,8 +1193,8 @@
<string name="deleteText" msgid="4200807474529938112">"Eliminar"</string>
<string name="inputMethod" msgid="1784759500516314751">"Método de introducción de texto"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Acciones de texto"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Escritura a mano no está disponible en este campo"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Escritura a mano no está disponible en campos de contraseña"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"La escritura a mano no está disponible en este campo"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"La escritura a mano no está disponible en campos de contraseña"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Atrás"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Cambiar método de introducción de texto"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"Queda poco espacio"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configura Desbloqueo facial de nuevo"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 63e1756..6f80461 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Teie tööprofiil pole selles seadmes enam saadaval"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Liiga palju paroolikatseid"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administraator keelas seadme isikliku kasutamise"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Privaatne ruum on eemaldatud"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Teie organisatsioon ei luba selles hallatud seadmes kasutada privaatseid ruume."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Seade on hallatud"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Teie organisatsioon haldab seda seadet ja võib jälgida võrguliiklust. Puudutage üksikasjade vaatamiseks."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Rakendused pääsevad teie asukohale juurde"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Seadistage näoga avamine uuesti"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 4fb4726..2a544f3 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Laneko profila ez dago erabilgarri gailu honetan"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Gehiegitan saiatu zara pasahitza idazten"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Erabilera pertsonalerako utzi du gailua administratzaileak"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Kendu egin da eremu pribatua"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Zure erakundeak ez ditu onartzen eremu pribatuak kudeatutako gailu honetan."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Jabeak kudeatzen du gailua"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Erakundeak kudeatzen du gailua eta baliteke sareko trafikoa gainbegiratzea. Sakatu hau xehetasunak ikusteko."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikazioek zure kokapena atzi dezakete"</string>
@@ -283,8 +285,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ahots-laguntza"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blokeatu"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Erantzun"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Jakinarazpen berria"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teklatu fisikoa"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Segurtasuna"</string>
@@ -2416,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguratu berriro aurpegi bidez desblokeatzeko eginbidea"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9a57d80..96d1203 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"نمایه کاری شما دیگر در این دستگاه دردسترس نیست"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"تلاشهای بسیار زیادی برای وارد کردن گذرواژه انجام شده است"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"سرپرست از این دستگاه برای استفاده شخصی چشمپوشی کرد"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"برنامهها میتوانند به مکانتان دسترسی پیدا کنند"</string>
@@ -283,8 +285,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"دستیار صوتی"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"قفل همه"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"۹۹۹+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"پاسخ دادن"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"اعلان جدید"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"صفحهکلید فیزیکی"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"امنیت"</string>
@@ -607,8 +608,8 @@
<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_uwb_ranging" msgid="8141915781475770665">"مشخص کردن موقعیت نسبی بین دستگاههای باند فوقوسیع اطراف"</string>
- <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"به برنامه اجازه داده میشود موقعیت نسبی بین دستگاههای باند فوقوسیع اطراف را مشخص کند"</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">"برقراری تعامل با دستگاههای Wi-Fi اطراف"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"به برنامه اجازه میدهد در دستگاههای Wi-Fi اطراف تبلیغ کند، به آنها متصل شود، و موقعیت نسبی آنها را تشخیص دهد"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"اطلاعات ترجیحی سرویس پولی NFC"</string>
@@ -2416,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"راهاندازی مجدد «قفلگشایی با چهره»"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 7062a89..8760948 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Työprofiilisi ei ole enää käytettävissä tällä laitteella."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Liikaa salasanayrityksiä"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Järjestelmänvalvoja luovutti laitteen henkilökohtaiseen käyttöön"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Yksityinen tila poistettu"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Organisaatio ei salli yksityisiä tiloja tällä hallinnoidulla laitteella."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Hallinnoitu laite"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisaatiosi hallinnoi tätä laitetta ja voi tarkkailla verkkoliikennettä. Katso lisätietoja napauttamalla."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Sovelluksilla on pääsy sijaintiisi"</string>
@@ -283,8 +285,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ääniapuri"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lukitse"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Vastaa"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Uusi ilmoitus"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fyysinen näppäimistö"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Turvallisuus"</string>
@@ -2416,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ota kasvojentunnistusavaus uudelleen käyttöön"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 9aa982f..4aeb86e 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus accessible sur cet appareil"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives d\'entrée du mot de passe"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a libéré l\'appareil pour un usage personnel"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Touchez ici pour obtenir plus d\'information."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Les applications peuvent accéder à votre position"</string>
@@ -2416,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configurer le Déverrouillage par reconnaissance faciale à nouveau"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index bb1b30d..f380133 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -162,7 +162,7 @@
<string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Connecté au réseau chiffré <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
<string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"La connexion à la carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g> est désormais plus sécurisée"</string>
<string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Connecté à un réseau non chiffré"</string>
- <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
+ <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Appels, messages et données sont plus vulnérables si vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
<string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Les appels, les messages et les données sont actuellement plus vulnérables lorsque vous utilisez votre carte SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nLorsque votre connexion sera à nouveau chiffrée, vous recevrez une nouvelle notification."</string>
<string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Paramètres de sécurité du réseau mobile"</string>
<string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"En savoir plus"</string>
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus disponible sur cet appareil"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives de saisie du mot de passe"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a mis l\'appareil à disposition pour un usage personnel"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Appuyez ici pour obtenir plus d\'informations."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Des applications peuvent accéder à votre position"</string>
@@ -2416,14 +2420,12 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
- <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 votre 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>
<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 votre visage."</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>
<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>
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 1808743..342d76b 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"O teu perfil de traballo xa non está dispoñible neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiados intentos de introdución do contrasinal"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso persoal"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo está xestionado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"A túa organización xestiona este dispositivo e pode controlar o tráfico de rede. Toca para obter máis detalles."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"As aplicacións poden acceder á túa localización"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configura de novo o desbloqueo facial"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index f9b6ae3..5aca7d6 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"આ ઉપકરણ પર તમારી કાર્યાલયની પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"પાસવર્ડના ઘણા વધુ પ્રયત્નો"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"વ્યવસ્થાપકે ડિવાઇસ વ્યક્તિગત ઉપયોગ માટે આપી દીધું છે"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"ડિવાઇસ મેનેજ થયેલ છે"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ઍપ તમારા સ્થાનને ઍક્સેસ કરી શકે છે"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ફેસ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index ae9b17c..3af0279 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"आपकी वर्क प्रोफ़ाइल अब इस डिवाइस पर उपलब्ध नहीं है"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"कई बार गलत पासवर्ड डाला गया"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"एडमिन ने निजी इस्तेमाल के लिए डिवाइस दे दिया है"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"डिवाइस प्रबंधित है"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"आपका संगठन इस डिवाइस का प्रबंधन करता है और वह नेटवर्क ट्रैफ़िक की निगरानी भी कर सकता है. विवरण के लिए टैप करें."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ऐप्लिकेशन आपकी जगह की जानकारी ऐक्सेस कर सकते हैं"</string>
@@ -1188,8 +1192,8 @@
<string name="deleteText" msgid="4200807474529938112">"मिटाएं"</string>
<string name="inputMethod" msgid="1784759500516314751">"इनपुट विधि"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"लेख क्रियाएं"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"इस फ़ील्ड में हैंडराइटिंग की सुविधा मौजूद नहीं है"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"पासवर्ड वाले फ़ील्ड में हैंडराइटिंग की सुविधा मौजूद नहीं है"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"हैंडराइटिंग की सुविधा, इस फ़ील्ड में काम नहीं करती है"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"हैंडराइटिंग की सुविधा, पासवर्ड वाले फ़ील्ड में काम नहीं करती है"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"वापस जाएं"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"इनपुट का तरीका बदलें"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"मेमोरी में जगह नहीं बची है"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"फ़ेस अनलॉक की सुविधा को दोबारा सेट अप करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0bd8be3..57caeec 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vaš poslovni profil više nije dostupan na ovom uređaju"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa zaporke"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za osobnu upotrebu"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Uređaj je upravljan"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može nadzirati mrežni promet. Dodirnite za pojedinosti."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacije mogu pristupiti vašoj lokaciji"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zaključaj"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Odgovor"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova obavijest"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizička tipkovnica"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sigurnost"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovno postavite otključavanje licem"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index aeebbdc..8447d79 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Munkaprofilja már nem hozzáférhető ezen az eszközön."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Túl sok jelszómegadási kísérlet"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Az adminisztrátor átadta az eszközt személyes használatra"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Felügyelt eszköz"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ezt az eszközt szervezete kezeli, és lehetséges, hogy a hálózati forgalmat is figyelik. További részletekért koppintson."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Az alkalmazások hozzáférhetnek az Ön tartózkodási helyéhez"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Hangsegéd"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zárolás"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Válasz"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Új értesítés"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizikai billentyűzet"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Biztonság"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Állítsa be újra az Arcalapú feloldást"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index a0e0bd2..e882794 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ձեր աշխատանքային պրոֆիլն այս սարքում այլևս հասանելի չէ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Գաղտնաբառը մուտքագրելու չափից շատ փորձեր են կատարվել"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Ադմինիստրատորը տրամադրել է սարքը անձնական օգտագործման համար"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Սարքը կառավարվում է"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ձեր կազմակերպությունը կառավարում է այս սարքը և կարող է վերահսկել ցանցի թրաֆիկը: Հպեք՝ մանրամասները դիտելու համար:"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Հավելվածներին հասանելի է ձեր տեղադրությունը"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ձայնային օգնութ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Արգելափակում"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Պատասխանել"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Նոր ծանուցում"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Ֆիզիկական ստեղնաշար"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Անվտանգություն"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Նորից կարգավորեք դեմքով ապակողպումը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index fb6180b..a075749 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil kerja tidak tersedia lagi di perangkat ini"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Terlalu banyak kesalahan sandi"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin melepaskan perangkat untuk penggunaan pribadi"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Perangkat ini ada yang mengelola"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi mengelola perangkat ini dan mungkin memantau traffic jaringan. Ketuk untuk melihat detailnya."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikasi dapat mengakses lokasi Anda"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Bantuan Suara"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Kunci total"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Balas"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Notifikasi baru"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Keyboard fisik"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Keamanan"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Siapkan Buka dengan Wajah lagi"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 5b38461..8b6f7c7 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vinnusniðið þitt er ekki lengur í boði á þessu tæki"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Of margar tilraunir til að slá inn aðgangsorð"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Kerfisstjóri lét af hendi tæki til einkanota"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Leynirými fjarlægt"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Fyrirtækið þitt leyfir ekki leynirými í þessu stýrða tæki."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Tækinu er stjórnað"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Fyrirtækið þitt stjórnar þessu tæki og kann að fylgjast með netnotkun. Ýttu hér til að fá upplýsingar."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Forrit hafa aðgang að staðsetningu þinni"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Setja upp andlitskenni aftur"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f22b653..abd1c29 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Il tuo profilo di lavoro non è più disponibile sul dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Troppi tentativi di inserimento della password"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'amministratore ha abbandonato il dispositivo per uso personale"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Il dispositivo è gestito"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Questo dispositivo è gestito dalla tua organizzazione, che potrebbe monitorare il traffico di rete. Tocca per i dettagli."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Le app possono accedere alla tua posizione"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blocco"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Rispondi"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nuova notifica"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tastiera fisica"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sicurezza"</string>
@@ -1903,7 +1906,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Richiedi il PIN per lo sblocco"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Richiedi sequenza di sblocco prima di sbloccare"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Richiedi password prima di sbloccare"</string>
- <string name="package_installed_device_owner" msgid="8684974629306529138">"Installato dall\'amministratore.\nVai alle impostazioni per visualizzare le autorizzazioni"</string>
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Installato dall\'amministratore.\nVai alle impostazioni per visualizzare le autorizzazioni concesse"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Aggiornato dall\'amministratore"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminato dall\'amministratore"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Riconfigura lo Sblocco con il Volto"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 3a924e1..0c70e91 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"פרופיל העבודה שלך אינו זמין עוד במכשיר הזה"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"בוצעו ניסיונות רבים מדי להזנת סיסמה"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"מנהל המערכת ביטל את האפשרות לשימוש במכשיר לצרכים אישיים"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"המכשיר מנוהל"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"הארגון שלך מנהל את המכשיר הזה והוא עשוי לנטר את התנועה ברשת. יש להקיש לקבלת פרטים."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"לאפליקציות יש הרשאת גישה למיקום שלך"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"האסיסטנט"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"נעילה"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"תשובה"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"התראה חדשה"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"מקלדת פיזית"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"אבטחה"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"הגדרה חוזרת של \'פתיחה ע\"י זיהוי הפנים\'"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index a802d90..4704e38 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"お使いの仕事用プロファイルはこのデバイスで使用できなくなりました"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"パスワード入力回数が上限に達しました"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"管理者により、デバイスの個人使用が許可されました"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"管理対象のデバイス"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"このデバイスは組織によって管理され、ネットワーク トラフィックが監視される場合があります。詳しくはタップしてください。"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"アプリに位置情報へのアクセスを許可しました"</string>
@@ -2395,7 +2399,7 @@
<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="profile_label_private" msgid="6463418670715290696">"非公開"</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>
<string name="profile_label_work_2" msgid="4691533661598632135">"仕事用 2"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"顔認証をもう一度設定してください"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 338ec1c..e0a507e 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"თქვენი სამსახურის პროფილი აღარ არის ხელმისაწვდომი ამ მოწყობილობაზე"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"დაფიქსირდა პაროლის შეყვანის ზედმეტად ბევრი მცდელობა"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ადმინისტრატორმა გაათავისუფლა მოწყობილობა პირადი გამოყენებისთვის"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"მოწყობილობა მართულია"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ამ მოწყობილობას თქვენი ორგანიზაცია მართავს და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია. შეეხეთ დამატებითი დეტალებისთვის."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"აპებს შეუძლია თქვენს მდებარეობაზე წვდომა"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"დააყენეთ სახით განბლოკვა ხელახლა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index e407c09..04c99a2 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жұмыс профиліңіз осы құрылғыда енді қолжетімді емес"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Құпия сөз көп рет қате енгізілді"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Әкімші құрылғыны жеке пайдалануға ұсынды."</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Құрылғы басқарылады"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін. Мәліметтер алу үшін түртіңіз."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Қолданбалар геодерегіңізді пайдалана алады"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Дауыс көмекшісі"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Құлыптау"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Жауап беру"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Жаңа хабарландыру"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физикалық пернетақта"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Қауіпсіздік"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Бет тану функциясын қайта реттеу"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index b021038..527745c 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"កម្រងព័ត៌មានការងាររបស់អ្នកលែងមាននៅលើឧបករណ៍នេះទៀតហើយ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ការព្យាយាមបញ្ចូលពាក្យសម្ងាត់ច្រើនដងពេកហើយ"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"អ្នកគ្រប់គ្រងបានបោះបង់ឧបករណ៍ចោលដោយសារការប្រើប្រាស់ផ្ទាល់ខ្លួន"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"ឧបករណ៍ស្ថិតក្រោមការគ្រប់គ្រង"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ស្ថាប័នរបស់អ្នកគ្រប់គ្រងឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ។ ចុចដើម្បីទទួលបានព័ត៌មានលម្អិត។"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"កម្មវិធីអាចចូលប្រើទីតាំងរបស់អ្នកបាន"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"រៀបចំការដោះសោដោយស្កេនមុខម្ដងទៀត"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 535c125..ade6f76 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಈ ಸಾಧನದಲ್ಲಿ ಈಗ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ಹಲವಾರು ಪಾಸ್ವರ್ಡ್ ಪ್ರಯತ್ನಗಳು"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ವೈಯಕ್ತಿಕ ಬಳಕೆಗಾಗಿ ನಿರ್ವಾಹಕರು ತೊರೆದ ಸಾಧನ"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದು ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ಗಮನವಿರಿಸಬಹುದು. ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ಆ್ಯಪ್ಗಳು ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ಫೇಸ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 7a8d324..c60482f 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"직장 프로필을 이 기기에서 더 이상 사용할 수 없습니다."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"비밀번호 입력을 너무 많이 시도함"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"관리자가 기기를 개인용으로 전환했습니다."</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"앱에서 위치 정보에 액세스할 수 있음"</string>
@@ -283,8 +285,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"음성 지원"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"잠금"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"답장"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"새 알림"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"물리적 키보드"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"보안"</string>
@@ -2416,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"얼굴 인식 잠금 해제 다시 설정"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 8a233a3..c23e49a 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жумуш профилиңиз бул түзмөктөн өчүрүлдү"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Өтө көп жолу сырсөздү киргизүү аракети жасалды"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Админ түзмөктөн жеке колдонуу үчүн баш тартты"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"Колдонмолор кайда жүргөнүңүздү көрө алат"</string>
@@ -283,8 +285,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Үн жардамчысы"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Бекем кулпулоо"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Жооп берүү"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Жаңы эскертме"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Аппараттык баскычтоп"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Коопсуздук"</string>
@@ -1189,8 +1190,8 @@
<string name="deleteText" msgid="4200807474529938112">"Өчүрүү"</string>
<string name="inputMethod" msgid="1784759500516314751">"Киргизүү ыкмасы"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Текст боюнча иштер"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Бул талаада жазып киргизүү колдоого алынбайт"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Сырсөз талаасында жазып киргизүү колдоого алынбайт"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Бул жерге кол менен жазганга болбойт"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Сырсөз киргизилүүчү жерге кол менен жаза албайсыз"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Артка"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Киргизүү ыкмасын өзгөртүү"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"Сактагычта орун калбай баратат"</string>
@@ -2416,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Жүзүнөн таанып ачуу функциясын кайрадан тууралаңыз"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index ec583038..12f59b7 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານບໍ່ສາມາດໃຊ້ໄດ້ໃນອຸປະກອນນີ້ອີກຕໍ່ໄປ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ລອງໃສ່ລະຫັດຜ່ານຫຼາຍເທື່ອເກີນໄປ"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ອຸປະກອນທີ່ຍົກເລີກແລ້ວສຳລັບການໃຊ້ສ່ວນບຸກຄົນ"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"ແອັບສາມາດເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານໄດ້"</string>
@@ -1188,8 +1190,8 @@
<string name="deleteText" msgid="4200807474529938112">"ລຶບ"</string>
<string name="inputMethod" msgid="1784759500516314751">"ຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"ການເຮັດວຽກຂອງຂໍ້ຄວາມ"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ການຂຽນດ້ວຍມືບໍ່ຖືກຮອງຮັບໃນຊ່ອງຂໍ້ມູນນີ້"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ການຂຽນດ້ວຍມືບໍ່ຖືກຮອງຮັບໃນຊ່ອງຂໍ້ມູນລະຫັດຜ່ານ"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ບໍ່ຮອງຮັບການຂຽນດ້ວຍມືໃນຊ່ອງຂໍ້ມູນນີ້"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ຊ່ອງຂໍ້ມູນລະຫັດຜ່ານບໍ່ຮອງຮັບການຂຽນດ້ວຍມື"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ກັບຄືນ"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ສະຫຼັບວິທີການປ້ອນຂໍ້ມູນ"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນກຳລັງຈະເຕັມ"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າຄືນໃໝ່"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index d3bf781..c4e228c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -203,6 +203,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Darbo profilis nebepasiekiamas šiame įrenginyje"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Per daug slaptažodžio bandymų"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratorius atmetė prašymą įrenginį naudoti asmeniniais tikslais"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Įrenginys yra tvarkomas"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Šį įrenginį tvarko organizacija ir gali stebėti tinklo srautą. Palieskite, kad gautumėte daugiau informacijos."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Programos gali pasiekti jūsų vietovę"</string>
@@ -2417,10 +2421,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Atrakinimo pagal veidą nustatymas iš naujo"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8be327d..c70abad 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jūsu darba profils šai ierīcē vairs nav pieejams."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Veikts pārāk daudz paroles ievadīšanas mēģinājumu."</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrators atteicās no tādas ierīces pārvaldības, ko var izmantot personiskām vajadzībām"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Ierīce tiek pārvaldīta"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Jūsu organizācija pārvalda šo ierīci un var uzraudzīt tīkla datplūsmu. Pieskarieties, lai saņemtu detalizētu informāciju."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Lietotne var piekļūt jūsu atrašanās vietas datiem"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Balss palīgs"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloķēšana"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"Pārsniedz"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Atbildēt"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Jauns paziņojums"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fiziskā tastatūra"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Drošība"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vēlreiz iestatiet autorizāciju pēc sejas"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index d8acc30..b3b2d73 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Вашиот работен профил веќе не е достапен на уредов"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Премногу обиди за внесување лозинка"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Уред откажан од администраторот за лична употреба"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Некој управува со уредот"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Вашата организација управува со уредов и можно е да го следи сообраќајот на мрежата. Допрете за детали."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Апликациите може да пристапуваат до вашата локација"</string>
@@ -1188,7 +1192,7 @@
<string name="deleteText" msgid="4200807474529938112">"Избриши"</string>
<string name="inputMethod" msgid="1784759500516314751">"Метод на внес"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Дејства со текст"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ракописот не е поддржан во полево"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ракописот не е поддржан во ова поле"</string>
<string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Ракописот не е поддржан во полињата за лозинка"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Префрлете го методот за внесување"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Поставете „Отклучување со лик“ повторно"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 747631a..97ce202 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ഈ ഉപകരണത്തിൽ തുടർന്നങ്ങോട്ട് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ ലഭ്യമല്ല"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"വളരെയധികം പാസ്വേഡ് ശ്രമങ്ങൾ"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"വ്യക്തിപരമായ ഉപയോഗത്തിനായി, ഉപകരണത്തിന്റെ ഔദ്യോഗിക ഉപയോഗം അഡ്മിൻ അവസാനിപ്പിച്ചു"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"ഉപകരണം മാനേജുചെയ്യുന്നുണ്ട്"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം, വിശദാംശങ്ങൾ അറിയാൻ ടാപ്പുചെയ്യുക."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ആപ്പുകൾക്ക് നിങ്ങളുടെ ലൊക്കേഷൻ ആക്സസ് ചെയ്യാനാകും"</string>
@@ -2147,7 +2151,7 @@
<string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ബാറ്ററി ലൈഫ് വർദ്ധിപ്പിക്കാൻ ബാറ്ററി ഉപയോഗം കുറയ്ക്കുന്നു"</string>
<string name="dynamic_mode_notification_title_v2" msgid="5072385242078021152">"ബാറ്ററി സേവർ ഓണാണ്"</string>
<string name="dynamic_mode_notification_summary_v2" msgid="2142444344663147938">"ബാറ്ററി ലൈഫ് വർദ്ധിപ്പിക്കാൻ ബാറ്ററി സേവർ ഓണാക്കിയിരിക്കുന്നു"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ബാറ്ററി ലാഭിക്കൽ"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ബാറ്ററി സേവർ"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"ബാറ്ററി സേവർ ഓഫാക്കിയിരിക്കുന്നു"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"ഫോണിൽ വേണ്ടത്ര ചാർജ് ഉണ്ട്. ഫീച്ചറുകൾക്ക് ഇനി നിയന്ത്രണമില്ല."</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"ടാബ്ലെറ്റിൽ വേണ്ടത്ര ചാർജ് ഉണ്ട്. ഫീച്ചറുകൾക്ക് ഇനി നിയന്ത്രണമില്ല."</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ഫെയ്സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 8d430ee..2d630ac 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Таны ажлын профайл энэ төхөөрөмжид боломжгүй байна"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Нууц үгийг хэт олон удаа буруу оруулсан байна"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Админ хувийн хэрэглээнд зориулж төхөөрөмжийн эрхийг хассан"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"Аппууд нь таны байршилд хандах боломжтой"</string>
@@ -283,8 +285,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Дуут туслах"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Түгжих"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Хариу бичих"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Шинэ мэдэгдэл"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Биет гар"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Аюулгүй байдал"</string>
@@ -1190,7 +1191,7 @@
<string name="inputMethod" msgid="1784759500516314751">"Оруулах арга"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Текст үйлдэл"</string>
<string name="error_handwriting_unsupported" msgid="7809438534946014050">"Гараар бичихийг энэ талбарт дэмждэггүй"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Гараар бичихийг нууц үгний талбаруудад дэмждэггүй"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Нууц үгний талбарт гараар бичихийг дэмждэггүй"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Буцах"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Оруулах аргыг сэлгэх"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"Сангийн хэмжээ дутагдаж байна"</string>
@@ -2416,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Царайгаар түгжээ тайлахыг дахин тохируулна уу"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 022f5c3f..a6e3e66 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"तुमचे कार्य प्रोफाइल आता या डिव्हाइसवर उपलब्ध नाही"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"बर्याचदा पासवर्ड टाकण्याचा प्रयत्न केला"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"वैयक्तिक वापरासाठी ॲडमिनने नियंत्रण सोडलेले डिव्हाइस"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"डिव्हाइस व्यवस्थापित केले आहे"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"तुमची संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ॲप्स तुमचे स्थान अॅक्सेस करू शकतात"</string>
@@ -1188,8 +1192,8 @@
<string name="deleteText" msgid="4200807474529938112">"हटवा"</string>
<string name="inputMethod" msgid="1784759500516314751">"इनपुट पद्धत"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"मजकूर क्रिया"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"या फील्डमध्ये हस्तलेखनला सपोर्ट नाही"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"पासवर्ड फील्डमध्ये हस्तलेखनला सपोर्ट नाही"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"या फील्डमध्ये हस्तलेखनाला सपोर्ट नाही"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"पासवर्ड फील्डमध्ये हस्तलेखनाला सपोर्ट नाही"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"मागे जा"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"इनपुट पद्धत स्विच करा"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"संचयन स्थान संपत आहे"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलॉक पुन्हा सेट करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 908f5a8..4e4189f 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil kerja anda tidak lagi tersedia pada peranti ini"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Terlalu banyak percubaan kata laluan"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Pentadbir melepaskan peranti untuk kegunaan peribadi"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Peranti ini diurus"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi anda mengurus peranti ini dan mungkin memantau trafik rangkaian. Ketik untuk mendapatkan butiran."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apl boleh mengakses lokasi anda"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Sediakan semula Buka Kunci Wajah"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 22fe7f2..fa449ca 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ဤစက်ပစ္စည်းတွင် သင်၏ အလုပ်ပရိုဖိုင်မရှိတော့ပါ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"စကားဝှက်ထည့်သွင်းရန် ကြိုးစားသည့် အကြိမ်အရေအတွက် အလွန်များသွား၍ ဖြစ်ပါသည်"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ပုဂ္ဂိုလ်ရေးအသုံးပြုရန်အတွက် စီမံခန့်ခွဲသူက စက်ပစ္စည်းထိန်းချုပ်မှုကို ရပ်တန့်လိုက်သည်"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"အက်ပ်များက သင်၏တည်နေရာကို ကြည့်နိုင်သည်"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3939f48..a07639b 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jobbprofilen din er ikke lenger tilgjengelig på denne enheten"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"For mange passordforsøk"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratoren overførte enheten til personlig bruk"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Enheten administreres"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasjonen din kontrollerer denne enheten og kan overvåke nettverkstrafikk. Trykk for å få mer informasjon."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apper har tilgang til posisjonen din"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Talehjelp"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Låsing"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Svar"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nytt varsel"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fysisk tastatur"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sikkerhet"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansiktslåsen på nytt"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 3253afa..284b3886 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"तपाईंको कार्य प्रोफाइल अब उप्रान्त यस डिभाइसमा उपलब्ध छैन"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"पासवर्ड प्रविष्ट गर्ने अत्यधिक गलत प्रयासहरू भए"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"व्यवस्थापकले यन्त्रलाई व्यक्तिगत प्रयोगका लागि अस्वीकार गर्नुभयो"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"एपहरूले तपाईंको स्थान प्रयोग गर्न सक्छन्"</string>
@@ -1171,7 +1173,7 @@
<string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="1532369154488982046">"सबैलाई चयन गर्नुहोस्"</string>
- <string name="cut" msgid="2561199725874745819">"काट्नुहोस्"</string>
+ <string name="cut" msgid="2561199725874745819">"कट् गर्नुहोस्"</string>
<string name="copy" msgid="5472512047143665218">"कपी गर्नुहोस्"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"क्लिपबोर्डमा कपी गर्न सकिएन"</string>
<string name="paste" msgid="461843306215520225">"टाँस्नुहोस्"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलक फेरि सेटअप गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 6ece574..0c55e6b 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Je werkprofiel is niet meer beschikbaar op dit apparaat"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Te veel wachtwoordpogingen"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"De beheerder heeft het apparaat afgestaan voor persoonlijk gebruik"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Privégedeelte verwijderd"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Je organisatie staat geen privégedeelten toe op dit beheerde apparaat."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Apparaat wordt beheerd"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Dit apparaat wordt beheerd door je organisatie. Het netwerkverkeer kan worden bijgehouden. Tik voor meer informatie."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Apps hebben toegang tot je locatie"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Ontgrendelen via gezichtsherkenning weer instellen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index ae67a74..d38d824 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ଏହି ଡିଭାଇସରେ ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲ୍ ଆଉ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ବହୁତ ଥର ଭୁଲ ପାସ୍ୱର୍ଡ ଲେଖିଛନ୍ତି"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ବ୍ୟକ୍ତିଗତ ବ୍ୟବହାର ପାଇଁ ଆଡ୍ମିନ୍ ଡିଭାଇସ୍କୁ ଅଲଗା କରିଛନ୍ତି"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"ଡିଭାଇସକୁ ପରିଚାଳନା କରାଯାଉଛି"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ଆପଣଙ୍କ ସଂସ୍ଥା ଏହି ଡିଭାଇସକୁ ପରିଚାଳନା କରନ୍ତି ଏବଂ ନେଟୱର୍କ ଟ୍ରାଫିକ୍ ନୀରିକ୍ଷଣ କରନ୍ତି। ବିବରଣୀ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ଆପଗୁଡ଼ିକ ଆପଣଙ୍କ ଲୋକେସନକୁ ଆକ୍ସେସ୍ କରିପାରିବ"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ଫେସ୍ ଅନଲକ୍ ପୁଣି ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 5e79a7c..61e1846 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹੁਣ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ਕਈ ਵਾਰ ਗਲਤ ਪਾਸਵਰਡ ਦਾਖਲ ਕੀਤਾ ਗਿਆ"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨਿੱਜੀ ਵਰਤੋਂ ਲਈ ਡੀਵਾਈਸ ਤਿਆਗਿਆ"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ਐਪਾਂ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀਆਂ ਹਨ"</string>
@@ -835,11 +839,11 @@
<string name="policylab_watchLogin" msgid="7599669460083719504">"ਸਕ੍ਰੀਨ ਅਣਲਾਕ ਕਰਨ ਦੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ \'ਤੇ ਨਿਗਰਾਨੀ ਰੱਖਣਾ"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਹੋਏ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰਨਾ ਅਤੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਵਾਰ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਟੈਬਲੈੱਟ ਨੂੰ ਲਾਕ ਕਰਨਾ ਜਾਂ ਟੈਬਲੈੱਟ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਉਣਾ।"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਹੋਏ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਆਪਣੇ Android TV ਡੀਵਾਈਸ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਆਪਣੇ Android TV ਡੀਵਾਈਸ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ, ਜੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
- <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦੀ ਨਿਗਰਾਨੀ ਕਰੋ ਅਤੇ ਜੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ, ਤਾਂ ਵਾਹਨ ਆਡੀਓ ਸਿਸਟਮ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਵਾਹਨ ਆਡੀਓ ਸਿਸਟਮ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
+ <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦੀ ਨਿਗਰਾਨੀ ਕਰੋ ਅਤੇ ਜੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ, ਤਾਂ ਇੰਫ਼ੋਟੇਨਮੈਂਟ ਸਿਸਟਮ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਇੰਫ਼ੋਟੇਨਮੈਂਟ ਸਿਸਟਮ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਗਿਣਤੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰੋ ਅਤੇ ਜੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ, ਤਾਂ ਫ਼ੋਨ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਫ਼ੋਨ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਹੋਏ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਟੈਬਲੈੱਟ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਟੈਬਲੈੱਟ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ, ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਹੋਏ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਆਪਣੇ Android TV ਡੀਵਾਈਸ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ, ਜੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
- <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦੀ ਨਿਗਰਾਨੀ ਕਰੋ ਅਤੇ ਜੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ, ਤਾਂ ਵਾਹਨ ਆਡੀਓ ਸਿਸਟਮ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਇਸ ਪ੍ਰੋਫਾਈਲ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦੀ ਨਿਗਰਾਨੀ ਕਰੋ ਅਤੇ ਜੇ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ, ਤਾਂ ਇੰਫ਼ੋਟੇਨਮੈਂਟ ਸਿਸਟਮ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਇਸ ਪ੍ਰੋਫਾਈਲ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਣਲਾਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਫ਼ੋਨ ਨੂੰ ਲਾਕ ਕਰੋ ਜਾਂ ਫ਼ੋਨ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
<string name="policylab_resetPassword" msgid="214556238645096520">"ਸਕ੍ਰੀਨ ਲਾਕ ਬਦਲੋ"</string>
<string name="policydesc_resetPassword" msgid="4626419138439341851">"ਸਕ੍ਰੀਨ ਲਾਕ ਬਦਲੋ।"</string>
@@ -848,13 +852,13 @@
<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>
+ <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਇੰਫ਼ੋਟੇਨਮੈਂਟ ਸਿਸਟਮ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰ ਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਫ਼ੋਨ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟਾਓ"</string>
<string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"ਉਪਭੋਗਤਾ ਡਾਟਾ ਮਿਟਾਓ"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਟੈਬਲੈੱਟ ਤੇ ਮੌਜੂਦ ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ Android TV ਡੀਵਾਈਸ \'ਤੇ ਮੌਜੂਦ ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
- <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"ਇਸ ਵਾਹਨ ਆਡੀਓ ਸਿਸਟਮ \'ਤੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਇਸ ਪ੍ਰੋਫਾਈਲ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
+ <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"ਇਸ ਇੰਫ਼ੋਟੇਨਮੈਂਟ ਸਿਸਟਮ \'ਤੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਇਸ ਪ੍ਰੋਫਾਈਲ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਫ਼ੋਨ ਤੇ ਮੌਜੂਦ ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
<string name="policylab_setGlobalProxy" msgid="215332221188670221">"ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ"</string>
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"ਜਦੋਂ ਨੀਤੀ ਚਾਲੂ ਹੋਵੇ ਤਾਂ ਵਰਤੇ ਜਾਣ ਲਈ ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ। ਕੇਵਲ ਡੀਵਾਈਸ ਮਾਲਕ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
@@ -2222,7 +2226,7 @@
<string name="miniresolver_call_information" msgid="6739417525304184083">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਕਾਲਾਂ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
<string name="miniresolver_sms_information" msgid="4311292661329483088">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਹੀ ਸੁਨੇਹੇ ਭੇਜਣ ਦਿੰਦੀ ਹੈ"</string>
<string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"ਤੁਸੀਂ ਸਿਰਫ਼ ਆਪਣੀ ਨਿੱਜੀ ਫ਼ੋਨ ਐਪ ਤੋਂ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰ ਸਕਦੇ ਹੋ। ਨਿੱਜੀ ਫ਼ੋਨ ਤੋਂ ਕੀਤੀਆਂ ਕਾਲਾਂ ਤੁਹਾਡੇ ਨਿੱਜੀ ਕਾਲ ਇਤਿਹਾਸ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤੀਆਂ ਜਾਣਗੀਆਂ।"</string>
- <string name="miniresolver_private_space_messages_information" msgid="111285656327622118">"ਤੁਸੀਂ ਸਿਰਫ਼ ਆਪਣੀ ਨਿੱਜੀ ਸੁਨੇਹਾ ਐਪ ਤੋਂ SMS ਸੁਨੇਹੇ ਭੇਜ ਸਕਦੇ ਹੋ।"</string>
+ <string name="miniresolver_private_space_messages_information" msgid="111285656327622118">"ਤੁਸੀਂ ਸਿਰਫ਼ ਆਪਣੀ ਪ੍ਰਾਈਵੇਟ ਸੁਨੇਹਾ ਐਪ ਤੋਂ SMS ਸੁਨੇਹੇ ਭੇਜ ਸਕਦੇ ਹੋ।"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ਨਿੱਜੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ਕੰਮ ਸੰਬੰਧੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
<string name="miniresolver_call" msgid="6386870060423480765">"ਕਾਲ ਕਰੋ"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d810710..fc09874 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -203,6 +203,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Twój profil służbowy nie jest już dostępny na tym urządzeniu"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zbyt wiele prób podania hasła"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator odstąpił urządzenie do użytku osobistego"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Urządzenie jest zarządzane"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Twoja organizacja zarządza tym urządzeniem i może monitorować ruch w sieci. Kliknij, by dowiedzieć się więcej."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacje mogą mieć dostęp do Twojej lokalizacji"</string>
@@ -2417,10 +2421,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Skonfiguruj ponownie rozpoznawanie twarzy"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index e3b49a0..2f666a6 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -202,6 +202,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Seu perfil de trabalho não está mais disponível neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Muitas tentativas de senha"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso pessoal"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Espaço privado removido"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Sua organização não permite espaços privados neste dispositivo gerenciado."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Os apps podem acessar seu local"</string>
@@ -284,8 +286,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ajuda de voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueio total"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">">999"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Responder"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova notificação"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Segurança"</string>
@@ -2417,10 +2418,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 512f697..9c9fb8d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -202,6 +202,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"O seu perfil de trabalho já não está disponível neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiadas tentativas de introdução da palavra-passe"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador anulou o dispositivo para utilização pessoal."</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Espaço privado removido"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"A sua organização não permite espaços privados neste dispositivo gerido."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerido"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede. Toque para obter mais detalhes."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"As apps podem aceder à sua localização"</string>
@@ -2416,10 +2418,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial novamente"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index e3b49a0..2f666a6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -202,6 +202,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Seu perfil de trabalho não está mais disponível neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Muitas tentativas de senha"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso pessoal"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Espaço privado removido"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Sua organização não permite espaços privados neste dispositivo gerenciado."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Os apps podem acessar seu local"</string>
@@ -284,8 +286,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ajuda de voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueio total"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">">999"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Responder"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova notificação"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Segurança"</string>
@@ -2417,10 +2418,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7de9952..76d69d2 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profilul de serviciu nu mai este disponibil pe acest dispozitiv"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Prea multe încercări de introducere a parolei"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratorul a retras dispozitivul pentru uz personal"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Dispozitivul este gestionat"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organizația ta gestionează acest dispozitiv și poate monitoriza traficul în rețea. Atinge pentru mai multe detalii."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplicațiile îți pot accesa locația"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistent vocal"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blocare strictă"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"˃999"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Răspunde"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificare nouă"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tastatură fizică"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Securitate"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Reconfigurează Deblocarea facială"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d999bf5..b21a13c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -203,6 +203,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ваш рабочий профиль больше не доступен на этом устройстве"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Слишком много попыток ввести пароль."</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор освободил устройство для личного использования"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Это управляемое устройство"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик. Подробнее…"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"У приложений есть доступ к вашим геоданным"</string>
@@ -285,8 +289,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Аудиоподсказки"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Блокировка входа"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">">999"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Ответить"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Новое уведомление"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физическая клавиатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Безопасность"</string>
@@ -2418,10 +2421,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Настройте фейсконтроль заново"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index a8eda4f..11e8d0e 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ඔබේ කාර්යාල පැතිකඩ මෙම උපාංගය මත තවදුරටත් ලබා ගැනීමට නොහැකිය"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"මුරපද උත්සාහ කිරීම් ඉතා වැඩි ගණනකි"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"පරිපාලක පුද්ගලික භාවිතය සඳහා උපාංගය අත්හැර දමන ලදී"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"උපාංගය කළමනාකරණය කෙරේ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ඔබගේ ආයතනය මෙම උපාංගය කළමනාකරණය කරන අතර එය ජාල තදබදය නිරීක්ෂණය කළ හැක. විස්තර සඳහා තට්ටු කරන්න."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"යෙදුම්වලට ඔබේ ස්ථානයට ප්රවේශ විය හැකිය"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"හඬ සහායක"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"අගුලු දැමීම"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"පිළිතුර"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"නව දැනුම්දීම"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"භෞතික යතුරු පුවරුව"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ආරක්ෂාව"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"මුහුණෙන් අගුලු හැරීම නැවත සකසන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 46897cb..39fee34 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -203,6 +203,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Váš pracovný profil už v tomto zariadení nie je k dispozícii"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Príliš veľa pokusov o zadanie hesla"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Správca uvoľnil toto zariadenie na osobné používanie"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Zariadenie je spravované"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku. Klepnutím zobrazíte podrobnosti."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikácie majú prístup k vašej polohe"</string>
@@ -285,8 +289,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Hlasový asistent"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Uzamknúť"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Odpovedať"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nové upozornenie"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fyzická klávesnica"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Zabezpečenie"</string>
@@ -1191,8 +1194,8 @@
<string name="deleteText" msgid="4200807474529938112">"Odstrániť"</string>
<string name="inputMethod" msgid="1784759500516314751">"Metóda vstupu"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Operácie s textom"</string>
- <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ručné písanie nie je v tomto poli podporované"</string>
- <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"V poliach pre heslá nie je ručné písanie podporované"</string>
+ <string name="error_handwriting_unsupported" msgid="7809438534946014050">"V tomto poli nie je rukopis podporovaný"</string>
+ <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"V poliach pre heslá nie je rukopis podporovaný"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Späť"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Prepnúť metódu vstupu"</string>
<string name="low_internal_storage_view_title" msgid="9024241779284783414">"Nedostatok ukladacieho priestoru"</string>
@@ -2398,9 +2401,9 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> a <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Môžete to zmeniť klepnutím."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyzické klávesnice sú nakonfigurované"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klávesnice si zobrazíte klepnutím"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Súkromný"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Súkromné"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Klon"</string>
- <string name="profile_label_work" msgid="3495359133038584618">"Pracovný"</string>
+ <string name="profile_label_work" msgid="3495359133038584618">"Pracovné"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"2. pracovný"</string>
<string name="profile_label_work_3" msgid="4834572253956798917">"3. pracovný"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Testovací"</string>
@@ -2418,10 +2421,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Znova nastavte odomknutie tvárou"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5c3696a..ee37cb8 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -203,6 +203,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vaš delovni profil ni več na voljo v tej napravi"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Preveč poskusov vnosa gesla"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Skrbnik je napravo prepustil osebni uporabi"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Zasebni prostor odstranjen"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Vaša organizacija ne dovoli zasebnih prostorov v tej upravljani napravi."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Naprava je upravljana"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja to napravo in lahko nadzira omrežni promet. Dotaknite se za podrobnosti."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacije imajo dostop do vaše lokacije"</string>
@@ -2417,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Vnovična nastavitev odklepanja z obrazom"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 4a6bdcb..1d09715 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profili yt i punës nuk është më i disponueshëm në këtë pajisje"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Shumë përpjekje për fjalëkalimin"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratori e refuzoi pajisjen për përdorim personal"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Pajisja është e menaxhuar"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organizata jote e menaxhon këtë pajisje dhe mund të monitorojë trafikun e rrjetit. Trokit për detaje."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Aplikacionet mund të kenë qasje te vendndodhja jote"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ndihma zanore"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blloko"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Përgjigju"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Njoftim i ri"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tastiera fizike"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Siguria"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguro \"Shkyçjen me fytyrë\" përsëri"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 86387c9..a610344 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -202,6 +202,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Пословни профил више није доступан на овом уређају"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Превише покушаја уноса лозинке"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор је уступио уређај за личну употребу"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Уређајем се управља"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Организација управља овим уређајем и може да надгледа мрежни саобраћај. Додирните за детаље."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Апликације могу да приступају вашој локацији"</string>
@@ -284,8 +288,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Гласовна помоћ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Закључавање"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Одговори"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Ново обавештење"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физичка тастатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Безбедност"</string>
@@ -2417,10 +2420,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Поново подесите откључавање лицем"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 6c15ad8..9cc174c 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jobbprofilen är inte längre tillgänglig på enheten"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"För många försök med lösenord"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratören tillåter inte längre privat bruk av enheten"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Enheten hanteras"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisationen hanterar den här enheten och kan övervaka nätverkstrafiken. Tryck om du vill veta mer."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Appar har åtkomst till din plats"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Låsning"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Svara"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Ny avisering"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fysiskt tangentbord"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Säkerhet"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurera ansiktslås igen"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index e8ba087..d1bd775 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Wasifu wako wa kazini haupatikani tena kwenye kifaa hiki"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Umejaribu kuweka nenosiri mara nyingi mno"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Msimamizi aliacha kutumia kifaa kwa matumizi ya binafsi"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Kifaa kinadhibitiwa"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Shirika lako linadhibiti kifaa hiki na huenda likafuatilia shughuli kwenye mtandao. Gusa ili upate maelezo zaidi."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Programu zinaweza kutambua mahali ulipo"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Weka tena mipangilio ya Kufungua kwa Uso"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 231b14c..9479033 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"இந்தச் சாதனத்தில் இனி பணிக் கணக்கு கிடைக்காது"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"கடவுச்சொல்லை அதிக முறை தவறாக முயற்சித்துவிட்டீர்கள்"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"நிர்வாகியால் தனிப்பட்ட உபயோகத்திற்காக ஒதுக்கப்பட்ட சாதனம்"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"சாதனம் நிர்வகிக்கப்படுகிறது"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"உங்கள் நிறுவனம் இந்தச் சாதனத்தை நிர்வகிக்கும், அத்துடன் அது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம். விவரங்களுக்கு, தட்டவும்."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ஆப்ஸ் உங்கள் இருப்பிடத்தை அணுக முடியும்"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"குரல் உதவி"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"பூட்டு"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"பதிலளி"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"புதிய அறிவிப்பு"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"கைமுறை கீபோர்டு"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"பாதுகாப்பு"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 5517dbf..05b23d5 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ఈ పరికరంలో మీ కార్యాలయ ప్రొఫైల్ ఇప్పుడు అందుబాటులో లేదు"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"చాలా ఎక్కువ పాస్వర్డ్ ప్రయత్నాలు చేశారు"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"వ్యక్తిగత వినియోగం కోసం నిర్వాహకులు పరికరాన్ని తీసి వేశారు"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"పరికరం నిర్వహించబడింది"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"మీ సంస్థ ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్వర్క్ ట్రాఫిక్ని పర్యవేక్షించవచ్చు. వివరాల కోసం నొక్కండి."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"యాప్లు మీ లొకేషన్ను యాక్సెస్ చేయగలవు"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ఫేస్ అన్లాక్ను మళ్లీ సెటప్ చేయండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 070875f..aa9d77d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"โปรไฟล์งานของคุณไม่สามารถใช้ในอุปกรณ์นี้อีกต่อไป"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"พยายามป้อนรหัสผ่านหลายครั้งเกินไป"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"ผู้ดูแลระบบปล่อยอุปกรณ์ให้คุณใช้งานส่วนตัว"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"อุปกรณ์มีการจัดการ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"องค์กรของคุณจัดการอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย แตะเพื่อดูรายละเอียด"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"แอปจะเข้าถึงตำแหน่งของคุณได้"</string>
@@ -2201,7 +2205,7 @@
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"การสนทนา"</string>
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"บทสนทนากลุ่ม"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
- <string name="resolver_personal_tab" msgid="2051260504014442073">"ส่วนตัว"</string>
+ <string name="resolver_personal_tab" msgid="2051260504014442073">"ส่วนบุคคล"</string>
<string name="resolver_work_tab" msgid="2690019516263167035">"งาน"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"มุมมองส่วนตัว"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"ดูงาน"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"ตั้งค่าการปลดล็อกด้วยใบหน้าอีกครั้ง"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 45a66a3..6b4be29 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Hindi na available sa device na ito ang iyong profile sa trabaho"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Masyadong maraming pagsubok sa password"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Inalis ng admin ang device para sa personal na paggamit"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Naalis ang pribadong space"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Hindi pinapayagan ng iyong organisasyon ang mga pribadong space sa pinapamahalaang device na ito."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Pinamamahalaan ang device"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Pinamamahalaan ng iyong organisasyon ang device na ito, at maaari nitong subaybayan ang trapiko sa network. I-tap para sa mga detalye."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Maa-access ng mga app ang iyong lokasyon"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"I-set up ulit ang Pag-unlock Gamit ang Mukha"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 64498b5..96780a0 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"İş profiliniz arık bu cihazda kullanılamıyor"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Çok fazla şifre denemesi yapıldı"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Yönetici, cihazı kişisel kullanım için serbest bıraktı"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz yönetiliyor"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Kuruluşunuz bu cihazı yönetmekte olup ağ trafiğini izleyebilir. Ayrıntılar için dokunun."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Uygulamalar konumunuza erişebilir"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Sesli Yardım"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Tam kilitleme"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Yanıtla"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Yeni bildirim"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fiziksel klavye"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Güvenlik"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Yüz Tanıma Kilidi\'ni tekrar kurun"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index fcea7bb..a64c990 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -203,6 +203,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Робочий профіль більше не доступний на цьому пристрої"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Забагато спроб ввести пароль"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Адміністратор не дозволив використовувати пристрій для особистих потреб"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Пристрій контролюється"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Адміністратор вашої організації контролює цей пристрій і відстежує мережевий трафік. Торкніться, щоб дізнатися більше."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Додаток має доступ до геоданих"</string>
@@ -285,8 +289,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Голос. підказки"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Блокування"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Відповісти"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Нове сповіщення"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Фізична клавіатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Безпека"</string>
@@ -2418,10 +2421,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Налаштуйте фейс-контроль повторно"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index da592a4..0436022 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"آپ کا دفتری پروفائل اس آلہ پر مزید دستیاب نہیں ہے"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"پاس ورڈ کی بہت ساری کوششیں"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"منتظم نے ذاتی استعمال کے لیے آلہ کو دستبردار کیا ہے"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"آلہ زیر انتظام ہے"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"آپ کی تنظیم اس آلے کا نظم کرتی ہے اور وہ نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے۔ تفاصیل کیلئے تھپتھپائیں۔"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"ایپس آپ کے مقام تک رسائی حاصل کر سکتی ہیں"</string>
@@ -2415,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"فیس اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 0ef4ddc..e5a45da 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Bu qurilmada endi ishchi profilingiz mavjud emas"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Parol ko‘p marta xato kiritildi"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator shaxsiy foydalanishga qoldirilgan qurilmani rad etdi"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Maxfiy makon olib tashlandi"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Tashkilotingiz mazkur boshqaruvdagi qurilmada maxfiy makon ochishni taqiqlagan."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Bu – boshqariladigan qurilma"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tashkilotingiz bu qurilmani boshqaradi va tarmoq trafigini nazorat qilishi mumkin. Tafsilotlar uchun bosing."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Ilovalar joylashuv axborotidan foydalana oladi"</string>
@@ -283,8 +285,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ovozli yordam"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Qulflash"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Javob berish"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Yangi bildirishnoma"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tashqi klaviatura"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Xavfsizlik"</string>
@@ -2416,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Yuz bilan ochishni qayta sozlash"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4f2a9fd..6047ea7 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Hồ sơ công việc của bạn không có sẵn trên thiết bị này nữa"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Quá nhiều lần nhập mật khẩu"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Quản trị viên đã từ bỏ quyền sở hữu thiết bị để cho phép dùng vào mục đích cá nhân"</string>
+ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"Đã xoá không gian riêng tư"</string>
+ <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Tổ chức của bạn không cho phép tạo không gian riêng tư trên thiết bị được quản lý này."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Thiết bị được quản lý"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tổ chức của bạn sẽ quản lý thiết bị này và có thể theo dõi lưu lượng truy cập mạng. Nhấn để biết chi tiết."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Ứng dụng có thể truy cập vào thông tin vị trí của bạn"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<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>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1024322..2503bf6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"您的工作资料已不在此设备上"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密码尝试次数过多"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"管理员已将该设备开放给个人使用"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"设备为受管理设备"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"贵单位会管理该设备,且可能会监控网络流量。点按即可了解详情。"</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"应用可以访问您的位置信息"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"语音助理"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"锁定"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"回复"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"新通知"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"实体键盘"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"安全性"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新设置“人脸解锁”功能"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index baf9ef5..7113146 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"你的工作設定檔無法再在此裝置上使用"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密碼輸入錯誤的次數過多"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"管理員已開放裝置供個人使用"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"應用程式可存取你的位置"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定「面孔解鎖」功能"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9eeb6dc..94a5d11 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -201,6 +201,8 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"你的工作資料夾已不在這個裝置上"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密碼輸入錯誤的次數過多"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"管理員將這部裝置開放給個人使用"</string>
+ <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="location_changed_notification_title" msgid="3620158742816699316">"應用程式可存取你的位置資訊"</string>
@@ -2415,10 +2417,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定人臉解鎖"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 7749b1b..bbf844e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -201,6 +201,10 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Iphrofayela yakho yomsebenzi ayisatholakali kule divayisi"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Imizamo yamaphasiwedi eminingi kakhulu"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Umphathi udedela idivayisi ngokusetshenziswa komuntu siqu"</string>
+ <!-- no translation found for private_space_deleted_by_admin (1484365588862066939) -->
+ <skip />
+ <!-- no translation found for private_space_deleted_by_admin_details (7007781735201818689) -->
+ <skip />
<string name="network_logging_notification_title" msgid="554983187553845004">"Idivayisi iphethwe"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Inhlangano yakho iphethe le divayisi futhi kungenzeka ingaqaphi ithrafikhi yenethiwekhi. Thephela imininingwane."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Izinhlelo zokusebenza zingakwazi ukufinyelela endaweni yakho"</string>
@@ -283,8 +287,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Isisekeli sezwi"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Khiya"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
- <skip />
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Phendula"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Isaziso esisha"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Ikhibhodi ephathekayo"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Ukuphepha"</string>
@@ -2416,10 +2419,8 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
- <skip />
+ <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>
<string name="face_dangling_notification_title" msgid="947852541060975473">"Setha Ukuvula Ngobuso futhi"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 97e753e..575573c 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -136,11 +136,6 @@
<item>@color/search_url_text_material_light</item>
</array>
- <array name="preloaded_freeform_multi_window_drawables">
- <item>@drawable/decor_maximize_button_dark</item>
- <item>@drawable/decor_maximize_button_light</item>
- </array>
-
<!-- Used in LocalePicker -->
<string-array translatable="false" name="special_locale_codes">
<!-- http://b/17150708 - ensure that the list of languages says "Arabic"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0676f72..0706b32 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1193,13 +1193,14 @@
<!-- Allows activities to be launched on a long press on power during device setup. -->
<bool name="config_allowStartActivityForLongPressOnPowerInSetup">false</bool>
- <!-- Control the behavior when the user short presses the settings button.
- 0 - Nothing
+ <!-- Control the behavior when the user presses the settings button.
+ 0 - Launch Settings activity
1 - Launch notification panel
+ 2 - Nothing
This needs to match the constants in
com/android/server/policy/PhoneWindowManager.java
-->
- <integer name="config_shortPressOnSettingsBehavior">0</integer>
+ <integer name="config_settingsKeyBehavior">0</integer>
<!-- Control the behavior when the user short presses the power button.
0 - Nothing
@@ -4199,13 +4200,6 @@
automatically try to pair with it when the device exits tablet mode. -->
<string translatable="false" name="config_packagedKeyboardName"></string>
- <!-- The device supports freeform window management. Windows have title bars and can be moved
- and resized. If you set this to true, you also need to add
- PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT feature to your device specification.
- The duplication is necessary, because this information is used before the features are
- available to the system.-->
- <bool name="config_freeformWindowManagement">false</bool>
-
<!-- If set, this will force all windows to draw the status bar background, including the apps
that have not requested doing so (via the WindowManager.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
flag). -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a956a43..87141c7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5991,8 +5991,6 @@
<string name="accessibility_system_action_dpad_right_label">Dpad Right</string>
<!-- Label for Dpad center action [CHAR LIMIT=NONE] -->
<string name="accessibility_system_action_dpad_center_label">Dpad Center</string>
- <!-- Accessibility description of caption view -->
- <string name="accessibility_freeform_caption">Caption bar of <xliff:g id="app_name">%1$s</xliff:g>.</string>
<!-- Text to tell the user that a package has been forced by themselves in the RESTRICTED bucket. [CHAR LIMIT=NONE] -->
<string name="as_app_forced_to_restricted_bucket">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4ae6c5e..bb73934 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -402,7 +402,6 @@
<java-symbol type="bool" name="config_supportMicNearUltrasound" />
<java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
<java-symbol type="bool" name="config_supportAudioSourceUnprocessed" />
- <java-symbol type="bool" name="config_freeformWindowManagement" />
<java-symbol type="bool" name="config_supportsBubble" />
<java-symbol type="bool" name="config_supportsMultiWindow" />
<java-symbol type="bool" name="config_supportsSplitScreenMultiWindow" />
@@ -1266,7 +1265,6 @@
<java-symbol type="array" name="networkAttributes" />
<java-symbol type="array" name="preloaded_color_state_lists" />
<java-symbol type="array" name="preloaded_drawables" />
- <java-symbol type="array" name="preloaded_freeform_multi_window_drawables" />
<java-symbol type="array" name="sim_colors" />
<java-symbol type="array" name="special_locale_codes" />
<java-symbol type="array" name="special_locale_names" />
@@ -1861,7 +1859,7 @@
<java-symbol type="integer" name="config_lidNavigationAccessibility" />
<java-symbol type="integer" name="config_lidOpenRotation" />
<java-symbol type="integer" name="config_longPressOnHomeBehavior" />
- <java-symbol type="integer" name="config_shortPressOnSettingsBehavior" />
+ <java-symbol type="integer" name="config_settingsKeyBehavior" />
<java-symbol type="layout" name="global_actions" />
<java-symbol type="layout" name="global_actions_item" />
<java-symbol type="layout" name="global_actions_silent_mode" />
@@ -2470,16 +2468,6 @@
<!-- From Phone -->
<java-symbol type="bool" name="config_built_in_sip_phone" />
- <java-symbol type="id" name="maximize_window" />
- <java-symbol type="id" name="close_window" />
- <java-symbol type="layout" name="decor_caption" />
- <java-symbol type="drawable" name="decor_caption_title_focused" />
- <java-symbol type="drawable" name="decor_close_button_dark" />
- <java-symbol type="drawable" name="decor_close_button_light" />
- <java-symbol type="drawable" name="decor_maximize_button_dark" />
- <java-symbol type="drawable" name="decor_maximize_button_light" />
- <java-symbol type="color" name="decor_button_dark_color" />
- <java-symbol type="color" name="decor_button_light_color" />
<java-symbol type="array" name="unloggable_phone_numbers" />
<!-- From TelephonyProvider -->
@@ -4470,8 +4458,6 @@
<java-symbol type="string" name="accessibility_system_action_dpad_right_label" />
<java-symbol type="string" name="accessibility_system_action_dpad_center_label" />
- <java-symbol type="string" name="accessibility_freeform_caption" />
-
<!-- For Wide Color Gamut -->
<java-symbol type="bool" name="config_enableWcgMode" />
diff --git a/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java b/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
index 17980ac..f8800cb 100644
--- a/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
+++ b/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
@@ -18,6 +18,7 @@
import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
+import static android.view.ContentRecordingSession.TASK_ID_UNKNOWN;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -45,6 +46,7 @@
@Presubmit
public class ContentRecordingSessionTest {
private static final int DISPLAY_ID = 1;
+ private static final int TASK_ID = 123;
private static final IBinder WINDOW_TOKEN = new Binder("DisplayContentWindowToken");
@Test
@@ -65,6 +67,16 @@
ContentRecordingSession session = ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_TASK);
assertThat(session.getTokenToRecord()).isEqualTo(WINDOW_TOKEN);
+ assertThat(session.getTaskId()).isEqualTo(TASK_ID_UNKNOWN);
+ }
+
+ @Test
+ public void testSecondaryTaskConstructor() {
+ ContentRecordingSession session =
+ ContentRecordingSession.createTaskSession(WINDOW_TOKEN, TASK_ID);
+ assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_TASK);
+ assertThat(session.getTokenToRecord()).isEqualTo(WINDOW_TOKEN);
+ assertThat(session.getTaskId()).isEqualTo(TASK_ID);
}
@Test
@@ -73,6 +85,7 @@
DEFAULT_DISPLAY);
assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_DISPLAY);
assertThat(session.getTokenToRecord()).isNull();
+ assertThat(session.getTaskId()).isEqualTo(TASK_ID_UNKNOWN);
}
@Test
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml
index 78c8881..297c490 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionCode="1"
android:versionName="1.0">
- <uses-sdk android:minSdkVersion="8"
+ <uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="18"/>
<application android:name="com.android.multidexlegacyandexception.TestApplication"
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/AndroidManifest.xml
index 1a60c1e..a208268 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionCode="1"
android:versionName="1.0">
- <uses-sdk android:minSdkVersion="8"
+ <uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="18"/>
<application android:name=".TestApplication"
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/AndroidManifest.xml
index 35369c7..bb2a201 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/AndroidManifest.xml
@@ -4,7 +4,7 @@
android:versionCode="1"
android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="8" />
+ <uses-sdk android:minSdkVersion="21" />
<instrumentation
android:name="com.android.test.runner.MultiDexTestRunner"
android:targetPackage="com.android.multidexlegacytestapp" />
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/AndroidManifest.xml
index 1cadfcd..b96566c 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/AndroidManifest.xml
@@ -4,7 +4,7 @@
android:versionCode="1"
android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="8" />
+ <uses-sdk android:minSdkVersion="21" />
<instrumentation
android:name="com.android.multidexlegacytestapp.test2.MultiDexAndroidJUnitRunner"
android:targetPackage="com.android.multidexlegacytestapp" />
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml
index 840daab..3ad61ca 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionCode="1"
android:versionName="1.0">
- <uses-sdk android:minSdkVersion="19"
+ <uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="19"/>
<application android:name="androidx.multidex.MultiDexApplication"
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests/AndroidManifest.xml
index e2fba4e..c644c36 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests/AndroidManifest.xml
@@ -4,7 +4,7 @@
android:versionCode="1"
android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="9" />
+ <uses-sdk android:minSdkVersion="21" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.framework.multidexlegacytestservices" />
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/AndroidManifest.xml
index 01285e7..f511c5f 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/AndroidManifest.xml
@@ -4,7 +4,7 @@
android:versionCode="1"
android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="9" />
+ <uses-sdk android:minSdkVersion="21" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
index 8c911c4..4730243 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionCode="1"
android:versionName="1.0">
- <uses-sdk android:minSdkVersion="9"
+ <uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="18"/>
<application android:name="androidx.multidex.MultiDexApplication"
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
index 1817e95..0bcf9fe 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionCode="2"
android:versionName="2.0">
- <uses-sdk android:minSdkVersion="9"
+ <uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="18"/>
<application android:name="androidx.multidex.MultiDexApplication"
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
index c8a41bc..5b7680d 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionCode="3"
android:versionName="3.0">
- <uses-sdk android:minSdkVersion="9"
+ <uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="18"/>
<application android:name="androidx.multidex.MultiDexApplication"
diff --git a/data/etc/preinstalled-packages-platform.xml b/data/etc/preinstalled-packages-platform.xml
index 7823277..f9fb84d 100644
--- a/data/etc/preinstalled-packages-platform.xml
+++ b/data/etc/preinstalled-packages-platform.xml
@@ -134,4 +134,19 @@
<install-in-user-type package="com.android.avatarpicker">
<install-in user-type="FULL" />
</install-in-user-type>
+
+ <!-- AiLabs Warp app pre-installed in hardware/google/pixel/common/pixel-common-device.mk -->
+ <install-in-user-type package="com.google.android.apps.warp">
+ <install-in user-type="FULL" />
+ <install-in user-type="PROFILE" />
+ <do-not-install-in user-type="android.os.usertype.profile.PRIVATE" />
+ </install-in-user-type>
+
+ <!-- Google Home app pre-installed on tangor devices in vendor/google/products/tangor_common.mk
+ -->
+ <install-in-user-type package="com.google.android.apps.chromecast.app">
+ <install-in user-type="FULL" />
+ <install-in user-type="PROFILE" />
+ <do-not-install-in user-type="android.os.usertype.profile.PRIVATE" />
+ </install-in-user-type>
</config>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 81d066f..532ecc6 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -56,7 +56,7 @@
<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>
+ <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Налады ўсплывальных чатаў у праграме \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Дадатковае меню"</string>
<string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Зноў дадаць у стос"</string>
<string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ад праграмы \"<xliff:g id="APP_NAME">%2$s</xliff:g>\""</string>
@@ -70,16 +70,16 @@
<string name="bubbles_app_settings" msgid="3617224938701566416">"Налады \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
<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_manage_title" msgid="7042699946735628035">"Кіруйце ўсплывальнымі апавяшчэннямі ў любы час"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Каб выключыць усплывальныя апавяшчэнні з гэтай праграмы, націсніце \"Кіраваць\""</string>
+ <string name="bubbles_user_education_title" msgid="2112319053732691899">"Усплывальныя чаты"</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_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_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_manage_title" msgid="6148404487810835924">"Кіруйце наладамі ўсплывальных апавяшчэнняў у любы час"</string>
+ <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Кіруйце наладамі ўсплывальных чатаў у любы час"</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>
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 05d8637..ee740fb 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
@@ -131,6 +131,11 @@
abstract fun preparePreCommitEnteringRectMovement()
/**
+ * Subclasses must provide a duration (in ms) for the post-commit part of the animation
+ */
+ abstract fun getPostCommitAnimationDuration(): Long
+
+ /**
* Returns a base transformation to apply to the entering target during pre-commit. The system
* will apply the default animation on top of it.
*/
@@ -259,7 +264,8 @@
.setSpring(postCommitFlingSpring)
flingAnimation.start()
- val valueAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(POST_COMMIT_DURATION)
+ val valueAnimator =
+ ValueAnimator.ofFloat(1f, 0f).setDuration(getPostCommitAnimationDuration())
valueAnimator.addUpdateListener { animation: ValueAnimator ->
val progress = animation.animatedFraction
onPostCommitProgress(progress)
@@ -522,7 +528,6 @@
internal const val MAX_SCALE = 0.9f
private const val MAX_SCRIM_ALPHA_DARK = 0.8f
private const val MAX_SCRIM_ALPHA_LIGHT = 0.2f
- private const val POST_COMMIT_DURATION = 300L
private const val SPRING_SCALE = 100f
private const val MAX_FLING_SCALE = 0.6f
}
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 ab359bd..c4aafea 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
@@ -33,6 +33,8 @@
import com.android.wm.shell.protolog.ShellProtoLogGroup
import com.android.wm.shell.shared.annotations.ShellMainThread
import javax.inject.Inject
+import kotlin.math.max
+import kotlin.math.min
/** Class that handles customized predictive cross activity back animations. */
@ShellMainThread
@@ -96,6 +98,12 @@
targetEnteringRect.set(startClosingRect)
}
+ override fun getPostCommitAnimationDuration(): Long {
+ return min(
+ MAX_POST_COMMIT_ANIM_DURATION, max(closeAnimation!!.duration, enterAnimation!!.duration)
+ )
+ }
+
override fun getPreCommitEnteringBaseTransformation(progress: Float): Transformation {
gestureProgress = progress
transformation.clear()
@@ -107,9 +115,9 @@
super.startBackAnimation(backMotionEvent)
if (
closeAnimation == null ||
- enterAnimation == null ||
- closingTarget == null ||
- enteringTarget == null
+ enterAnimation == null ||
+ closingTarget == null ||
+ enteringTarget == null
) {
ProtoLog.d(
ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW,
@@ -125,10 +133,13 @@
super.onPostCommitProgress(linearProgress)
if (closingTarget == null || enteringTarget == null) return
- // TODO: Should we use the duration from the custom xml spec for the post-commit animation?
- applyTransform(closingTarget!!.leash, currentClosingRect, linearProgress, closeAnimation!!)
- val enteringProgress =
- MathUtils.lerp(gestureProgress * PRE_COMMIT_MAX_PROGRESS, 1f, linearProgress)
+ val closingProgress = closeAnimation!!.getPostCommitProgress(linearProgress)
+ applyTransform(closingTarget!!.leash, currentClosingRect, closingProgress, closeAnimation!!)
+ val enteringProgress = MathUtils.lerp(
+ gestureProgress * PRE_COMMIT_MAX_PROGRESS,
+ 1f,
+ enterAnimation!!.getPostCommitProgress(linearProgress)
+ )
applyTransform(
enteringTarget!!.leash,
currentEnteringRect,
@@ -175,6 +186,19 @@
return false
}
+ private fun Animation.getPostCommitProgress(linearProgress: Float): Float {
+ return when (duration) {
+ 0L -> 1f
+ else -> min(
+ 1f,
+ getPostCommitAnimationDuration() / min(
+ MAX_POST_COMMIT_ANIM_DURATION,
+ duration
+ ).toFloat() * linearProgress
+ )
+ }
+ }
+
class AnimationLoadResult {
var closeAnimation: Animation? = null
var enterAnimation: Animation? = null
@@ -183,6 +207,7 @@
companion object {
private const val PRE_COMMIT_MAX_PROGRESS = 0.2f
+ private const val MAX_POST_COMMIT_ANIM_DURATION = 2000L
}
}
@@ -226,7 +251,7 @@
// Try to get animation from Activity#overrideActivityTransition
if (
enterAnimation && animationInfo.customEnterAnim != 0 ||
- !enterAnimation && animationInfo.customExitAnim != 0
+ !enterAnimation && animationInfo.customExitAnim != 0
) {
a =
transitionAnimation.loadAppTransitionAnimation(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt
index 9f07e5b..44752fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/DefaultCrossActivityBackAnimation.kt
@@ -71,6 +71,8 @@
targetEnteringRect.scaleCentered(MAX_SCALE)
}
+ override fun getPostCommitAnimationDuration() = POST_COMMIT_DURATION
+
override fun onGestureCommitted(velocity: Float) {
// We enter phase 2 of the animation, the starting coordinates for phase 2 are the current
// coordinate of the gesture driven phase. Let's update the start and target rects and kick
@@ -93,4 +95,9 @@
applyTransform(enteringTarget?.leash, currentEnteringRect, 1f)
applyTransaction()
}
+
+
+ companion object {
+ private const val POST_COMMIT_DURATION = 300L
+ }
}
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 bc63db3..fac9bf6 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
@@ -344,7 +344,7 @@
pw.println("Expanded bubble state:");
pw.println(" expandedBubbleKey: " + mExpandedBubble.getKey());
- final BubbleExpandedView expandedView = mExpandedBubble.getExpandedView();
+ final BubbleExpandedView expandedView = getExpandedView();
if (expandedView != null) {
pw.println(" expandedViewVis: " + expandedView.getVisibility());
@@ -815,10 +815,11 @@
private float getScrimAlphaForDrag(float dragAmount) {
// dragAmount should be negative as we allow scroll up only
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
float alphaRange = BUBBLE_EXPANDED_SCRIM_ALPHA - MIN_SCRIM_ALPHA_FOR_DRAG;
- int dragMax = mExpandedBubble.getExpandedView().getContentHeight();
+ int dragMax = expandedView.getContentHeight();
float dragFraction = dragAmount / dragMax;
return Math.max(BUBBLE_EXPANDED_SCRIM_ALPHA - alphaRange * dragFraction,
@@ -1120,33 +1121,35 @@
mExpandedViewAlphaAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
// We need to be Z ordered on top in order for alpha animations to work.
- mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(true);
- mExpandedBubble.getExpandedView().setAnimating(true);
+ expandedView.setSurfaceZOrderedOnTop(true);
+ expandedView.setAnimating(true);
mExpandedViewContainer.setVisibility(VISIBLE);
}
}
@Override
public void onAnimationEnd(Animator animation) {
- if (mExpandedBubble != null
- && mExpandedBubble.getExpandedView() != null
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null
// The surface needs to be Z ordered on top for alpha values to work on the
// TaskView, and if we're temporarily hidden, we are still on the screen
// with alpha = 0f until we animate back. Stay Z ordered on top so the alpha
// = 0f remains in effect.
&& !mExpandedViewTemporarilyHidden) {
- mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
- mExpandedBubble.getExpandedView().setAnimating(false);
+ expandedView.setSurfaceZOrderedOnTop(false);
+ expandedView.setAnimating(false);
}
}
});
mExpandedViewAlphaAnimator.addUpdateListener(valueAnimator -> {
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
float alpha = (float) valueAnimator.getAnimatedValue();
- mExpandedBubble.getExpandedView().setContentAlpha(alpha);
- mExpandedBubble.getExpandedView().setBackgroundAlpha(alpha);
+ expandedView.setContentAlpha(alpha);
+ expandedView.setBackgroundAlpha(alpha);
}
});
@@ -1390,7 +1393,7 @@
}
final boolean seen = getPrefBoolean(ManageEducationView.PREF_MANAGED_EDUCATION);
final boolean shouldShow = (!seen || BubbleDebugConfig.forceShowUserEducation(mContext))
- && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null;
+ && getExpandedView() != null;
ProtoLog.d(WM_SHELL_BUBBLES, "Show manage edu=%b", shouldShow);
if (shouldShow && BubbleDebugConfig.neverShowUserEducation(mContext)) {
Log.w(TAG, "Want to show manage edu, but it is forced hidden");
@@ -1417,9 +1420,9 @@
* Show manage education if was not showing before.
*/
private void showManageEdu() {
- if (mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) return;
- mManageEduView.show(mExpandedBubble.getExpandedView(),
- mStackAnimationController.isStackOnLeftSide());
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView == null) return;
+ mManageEduView.show(expandedView, mStackAnimationController.isStackOnLeftSide());
}
@VisibleForTesting
@@ -1931,6 +1934,11 @@
return mExpandedBubble;
}
+ @Nullable
+ private BubbleExpandedView getExpandedView() {
+ return mExpandedBubble != null ? mExpandedBubble.getExpandedView() : null;
+ }
+
// via BubbleData.Listener
@SuppressLint("ClickableViewAccessibility")
void addBubble(Bubble bubble) {
@@ -2110,13 +2118,11 @@
// If we're expanded, screenshot the currently expanded bubble (before expanding the newly
// selected bubble) so we can animate it out.
- if (mIsExpanded && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null
- && !mExpandedViewTemporarilyHidden) {
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
- // Before screenshotting, have the real TaskView show on top of other surfaces
- // so that the screenshot doesn't flicker on top of it.
- mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(true);
- }
+ BubbleExpandedView expandedView = getExpandedView();
+ if (mIsExpanded && expandedView != null && !mExpandedViewTemporarilyHidden) {
+ // Before screenshotting, have the real TaskView show on top of other surfaces
+ // so that the screenshot doesn't flicker on top of it.
+ expandedView.setSurfaceZOrderedOnTop(true);
try {
screenshotAnimatingOutBubbleIntoSurface((success) -> {
@@ -2136,7 +2142,7 @@
private void showNewlySelectedBubble(BubbleViewProvider bubbleToSelect) {
final BubbleViewProvider previouslySelected = mExpandedBubble;
mExpandedBubble = bubbleToSelect;
- mExpandedViewAnimationController.setExpandedView(mExpandedBubble.getExpandedView());
+ mExpandedViewAnimationController.setExpandedView(getExpandedView());
if (mIsExpanded) {
hideCurrentInputMethod();
@@ -2445,8 +2451,7 @@
mBubbleContainer.animate().translationX(0).start();
}
mExpandedAnimationController.expandFromStack(() -> {
- if (mIsExpanded && mExpandedBubble != null
- && mExpandedBubble.getExpandedView() != null) {
+ if (mIsExpanded && getExpandedView() != null) {
maybeShowManageEdu();
}
updateOverflowDotVisibility(true /* expanding */);
@@ -2509,13 +2514,14 @@
}
mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
- mExpandedBubble.getExpandedView().setContentAlpha(0f);
- mExpandedBubble.getExpandedView().setBackgroundAlpha(0f);
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
+ expandedView.setContentAlpha(0f);
+ expandedView.setBackgroundAlpha(0f);
// We'll be starting the alpha animation after a slight delay, so set this flag early
// here.
- mExpandedBubble.getExpandedView().setAnimating(true);
+ expandedView.setAnimating(true);
}
mDelayedAnimation = () -> {
@@ -2545,10 +2551,9 @@
.withEndActions(() -> {
mExpandedViewContainer.setAnimationMatrix(null);
afterExpandedViewAnimation();
- if (mExpandedBubble != null
- && mExpandedBubble.getExpandedView() != null) {
- mExpandedBubble.getExpandedView()
- .setSurfaceZOrderedOnTop(false);
+ BubbleExpandedView expView = getExpandedView();
+ if (expView != null) {
+ expView.setSurfaceZOrderedOnTop(false);
}
})
.start();
@@ -2613,12 +2618,13 @@
};
mExpandedViewAnimationController.animateCollapse(collapseBackToStack, after,
collapsePosition);
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
// When the animation completes, we should no longer be showing the content.
// This won't actually update content visibility immediately, if we are currently
// animating. But updates the internal state for the content to be hidden after
// animation completes.
- mExpandedBubble.getExpandedView().setContentVisibility(false);
+ expandedView.setContentVisibility(false);
}
}
@@ -2710,10 +2716,10 @@
// expanded view animation might not actually set the z ordering for the
// expanded view correctly, because the view may still be temporarily
// hidden. So set it again here.
- BubbleExpandedView bev = mExpandedBubble.getExpandedView();
- if (bev != null) {
- mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
- mExpandedBubble.getExpandedView().setAnimating(false);
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
+ expandedView.setSurfaceZOrderedOnTop(false);
+ expandedView.setAnimating(false);
}
})
.start();
@@ -2785,13 +2791,13 @@
if (mIsExpanded) {
mExpandedViewAnimationController.animateForImeVisibilityChange(visible);
- if (mPositioner.showBubblesVertically()
- && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (mPositioner.showBubblesVertically() && expandedView != null) {
float selectedY = mPositioner.getExpandedBubbleXY(getState().selectedIndex,
getState()).y;
float newExpandedViewTop = mPositioner.getExpandedViewY(mExpandedBubble, selectedY);
- mExpandedBubble.getExpandedView().setImeVisible(visible);
- if (!mExpandedBubble.getExpandedView().isUsingMaxHeight()) {
+ expandedView.setImeVisible(visible);
+ if (!expandedView.isUsingMaxHeight()) {
mExpandedViewContainer.animate().translationY(newExpandedViewTop);
}
List<Animator> animList = new ArrayList<>();
@@ -3148,7 +3154,8 @@
// This should not happen, since the manage menu is only visible when there's an expanded
// bubble. If we end up in this state, just hide the menu immediately.
- if (mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView == null) {
mManageMenu.setVisibility(View.INVISIBLE);
mManageMenuScrim.setVisibility(INVISIBLE);
mSysuiProxyProvider.getSysuiProxy().onManageMenuExpandChanged(false /* show */);
@@ -3194,8 +3201,8 @@
}
}
- if (mExpandedBubble.getExpandedView().getTaskView() != null) {
- mExpandedBubble.getExpandedView().getTaskView().setObscuredTouchRect(mShowingManage
+ if (expandedView.getTaskView() != null) {
+ expandedView.getTaskView().setObscuredTouchRect(mShowingManage
? new Rect(0, 0, getWidth(), getHeight())
: null);
}
@@ -3205,8 +3212,8 @@
// When the menu is open, it should be at these coordinates. The menu pops out to the right
// in LTR and to the left in RTL.
- mExpandedBubble.getExpandedView().getManageButtonBoundsOnScreen(mTempRect);
- final float margin = mExpandedBubble.getExpandedView().getManageButtonMargin();
+ expandedView.getManageButtonBoundsOnScreen(mTempRect);
+ final float margin = expandedView.getManageButtonMargin();
final float targetX = isLtr
? mTempRect.left - margin
: mTempRect.right + margin - mManageMenu.getWidth();
@@ -3230,9 +3237,10 @@
.withEndActions(() -> {
View child = mManageMenu.getChildAt(0);
child.requestAccessibilityFocus();
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expView = getExpandedView();
+ if (expView != null) {
// Update the AV's obscured touchable region for the new state.
- mExpandedBubble.getExpandedView().updateObscuredTouchableRegion();
+ expView.updateObscuredTouchableRegion();
}
})
.start();
@@ -3247,9 +3255,10 @@
.spring(DynamicAnimation.TRANSLATION_Y, targetY + menuHeight / 4f)
.withEndActions(() -> {
mManageMenu.setVisibility(View.INVISIBLE);
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expView = getExpandedView();
+ if (expView != null) {
// Update the AV's obscured touchable region for the new state.
- mExpandedBubble.getExpandedView().updateObscuredTouchableRegion();
+ expView.updateObscuredTouchableRegion();
}
})
.start();
@@ -3276,9 +3285,8 @@
private void updateExpandedBubble() {
mExpandedViewContainer.removeAllViews();
- if (mIsExpanded && mExpandedBubble != null
- && mExpandedBubble.getExpandedView() != null) {
- BubbleExpandedView bev = mExpandedBubble.getExpandedView();
+ BubbleExpandedView bev = getExpandedView();
+ if (mIsExpanded && bev != null) {
bev.setContentVisibility(false);
bev.setAnimating(!mIsExpansionAnimating);
mExpandedViewContainerMatrix.setScaleX(0f);
@@ -3306,9 +3314,8 @@
}
private void updateManageButtonListener() {
- if (mIsExpanded && mExpandedBubble != null
- && mExpandedBubble.getExpandedView() != null) {
- BubbleExpandedView bev = mExpandedBubble.getExpandedView();
+ BubbleExpandedView bev = getExpandedView();
+ if (mIsExpanded && bev != null) {
bev.setManageClickListener((view) -> {
showManageMenu(true /* show */);
});
@@ -3325,14 +3332,13 @@
* expanded bubble.
*/
private void screenshotAnimatingOutBubbleIntoSurface(Consumer<Boolean> onComplete) {
- if (!mIsExpanded || mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) {
+ final BubbleExpandedView animatingOutExpandedView = getExpandedView();
+ if (!mIsExpanded || animatingOutExpandedView == null) {
// You can't animate null.
onComplete.accept(false);
return;
}
- final BubbleExpandedView animatingOutExpandedView = mExpandedBubble.getExpandedView();
-
// Release the previous screenshot if it hasn't been released already.
if (mAnimatingOutBubbleBuffer != null) {
releaseAnimatingOutBubbleBuffer();
@@ -3364,8 +3370,7 @@
mAnimatingOutSurfaceContainer.setTranslationX(translationX);
mAnimatingOutSurfaceContainer.setTranslationY(0);
- final int[] taskViewLocation =
- mExpandedBubble.getExpandedView().getTaskViewLocationOnScreen();
+ final int[] taskViewLocation = animatingOutExpandedView.getTaskViewLocationOnScreen();
final int[] surfaceViewLocation = mAnimatingOutSurfaceView.getLocationOnScreen();
// Translate the surface to overlap the real TaskView.
@@ -3427,15 +3432,15 @@
int[] paddings = mPositioner.getExpandedViewContainerPadding(
mStackAnimationController.isStackOnLeftSide(), isOverflowExpanded);
mExpandedViewContainer.setPadding(paddings[0], paddings[1], paddings[2], paddings[3]);
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
PointF p = mPositioner.getExpandedBubbleXY(getBubbleIndex(mExpandedBubble),
getState());
mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY(mExpandedBubble,
mPositioner.showBubblesVertically() ? p.y : p.x));
mExpandedViewContainer.setTranslationX(0f);
- mExpandedBubble.getExpandedView().updateTaskViewContentWidth();
- mExpandedBubble.getExpandedView().updateView(
- mExpandedViewContainer.getLocationOnScreen());
+ expandedView.updateTaskViewContentWidth();
+ expandedView.updateView(mExpandedViewContainer.getLocationOnScreen());
updatePointerPosition(false /* forIme */);
}
@@ -3508,7 +3513,8 @@
* the pointer is animated to the location.
*/
private void updatePointerPosition(boolean forIme) {
- if (mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) {
+ BubbleExpandedView expandedView = getExpandedView();
+ if (mExpandedBubble == null || expandedView == null) {
return;
}
int index = getBubbleIndex(mExpandedBubble);
@@ -3519,7 +3525,7 @@
float bubblePosition = mPositioner.showBubblesVertically()
? position.y
: position.x;
- mExpandedBubble.getExpandedView().setPointerPosition(bubblePosition,
+ expandedView.setPointerPosition(bubblePosition,
mStackOnLeftOrWillBe, forIme /* animate */);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index 95d4714..109868d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -20,9 +20,7 @@
import com.android.wm.shell.protolog.ShellProtoLogGroup
import com.android.wm.shell.util.KtProtoLog
-/**
- * Event logger for logging desktop mode session events
- */
+/** Event logger for logging desktop mode session events */
class DesktopModeEventLogger {
/**
* Logs the enter of desktop mode having session id [sessionId] and the reason [enterReason] for
@@ -32,13 +30,16 @@
KtProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging session enter, session: %s reason: %s",
- sessionId, enterReason.name
+ sessionId,
+ enterReason.name
)
- FrameworkStatsLog.write(DESKTOP_MODE_ATOM_ID,
+ FrameworkStatsLog.write(
+ DESKTOP_MODE_ATOM_ID,
/* event */ FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EVENT__ENTER,
/* enterReason */ enterReason.reason,
/* exitReason */ 0,
- /* session_id */ sessionId)
+ /* session_id */ sessionId
+ )
}
/**
@@ -49,13 +50,16 @@
KtProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging session exit, session: %s reason: %s",
- sessionId, exitReason.name
+ sessionId,
+ exitReason.name
)
- FrameworkStatsLog.write(DESKTOP_MODE_ATOM_ID,
+ FrameworkStatsLog.write(
+ DESKTOP_MODE_ATOM_ID,
/* event */ FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EVENT__EXIT,
/* enterReason */ 0,
/* exitReason */ exitReason.reason,
- /* session_id */ sessionId)
+ /* session_id */ sessionId
+ )
}
/**
@@ -66,9 +70,11 @@
KtProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging task added, session: %s taskId: %s",
- sessionId, taskUpdate.instanceId
+ sessionId,
+ taskUpdate.instanceId
)
- FrameworkStatsLog.write(DESKTOP_MODE_TASK_UPDATE_ATOM_ID,
+ FrameworkStatsLog.write(
+ DESKTOP_MODE_TASK_UPDATE_ATOM_ID,
/* task_event */
FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_ADDED,
/* instance_id */
@@ -84,7 +90,8 @@
/* task_y */
taskUpdate.taskY,
/* session_id */
- sessionId)
+ sessionId
+ )
}
/**
@@ -95,9 +102,11 @@
KtProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging task remove, session: %s taskId: %s",
- sessionId, taskUpdate.instanceId
+ sessionId,
+ taskUpdate.instanceId
)
- FrameworkStatsLog.write(DESKTOP_MODE_TASK_UPDATE_ATOM_ID,
+ FrameworkStatsLog.write(
+ DESKTOP_MODE_TASK_UPDATE_ATOM_ID,
/* task_event */
FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_REMOVED,
/* instance_id */
@@ -113,7 +122,8 @@
/* task_y */
taskUpdate.taskY,
/* session_id */
- sessionId)
+ sessionId
+ )
}
/**
@@ -124,9 +134,11 @@
KtProtoLog.v(
ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
"DesktopModeLogger: Logging task info changed, session: %s taskId: %s",
- sessionId, taskUpdate.instanceId
+ sessionId,
+ taskUpdate.instanceId
)
- FrameworkStatsLog.write(DESKTOP_MODE_TASK_UPDATE_ATOM_ID,
+ FrameworkStatsLog.write(
+ DESKTOP_MODE_TASK_UPDATE_ATOM_ID,
/* task_event */
FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_INFO_CHANGED,
/* instance_id */
@@ -142,7 +154,8 @@
/* task_y */
taskUpdate.taskY,
/* session_id */
- sessionId)
+ sessionId
+ )
}
companion object {
@@ -160,12 +173,8 @@
* stats/atoms/desktopmode/desktopmode_extensions_atoms.proto
*/
enum class EnterReason(val reason: Int) {
- UNKNOWN_ENTER(
- FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__UNKNOWN_ENTER
- ),
- OVERVIEW(
- FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__OVERVIEW
- ),
+ UNKNOWN_ENTER(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__UNKNOWN_ENTER),
+ OVERVIEW(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__OVERVIEW),
APP_HANDLE_DRAG(
FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__APP_HANDLE_DRAG
),
@@ -178,9 +187,7 @@
KEYBOARD_SHORTCUT_ENTER(
FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__KEYBOARD_SHORTCUT_ENTER
),
- SCREEN_ON(
- FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__SCREEN_ON
- );
+ SCREEN_ON(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__SCREEN_ON)
}
/**
@@ -188,12 +195,8 @@
* stats/atoms/desktopmode/desktopmode_extensions_atoms.proto
*/
enum class ExitReason(val reason: Int) {
- UNKNOWN_EXIT(
- FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__UNKNOWN_EXIT
- ),
- DRAG_TO_EXIT(
- FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__DRAG_TO_EXIT
- ),
+ UNKNOWN_EXIT(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__UNKNOWN_EXIT),
+ DRAG_TO_EXIT(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__DRAG_TO_EXIT),
APP_HANDLE_MENU_BUTTON_EXIT(
FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__APP_HANDLE_MENU_BUTTON_EXIT
),
@@ -203,16 +206,12 @@
RETURN_HOME_OR_OVERVIEW(
FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME
),
- TASK_FINISHED(
- FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__TASK_FINISHED
- ),
- SCREEN_OFF(
- FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__SCREEN_OFF
- )
+ TASK_FINISHED(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__TASK_FINISHED),
+ SCREEN_OFF(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__SCREEN_OFF)
}
private const val DESKTOP_MODE_ATOM_ID = FrameworkStatsLog.DESKTOP_MODE_UI_CHANGED
private const val DESKTOP_MODE_TASK_UPDATE_ATOM_ID =
FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE
}
-}
\ No newline at end of file
+}
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 0b7a3e8..5d8e340 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
@@ -60,8 +60,9 @@
private val idSequence: InstanceIdSequence by lazy { InstanceIdSequence(Int.MAX_VALUE) }
init {
- if (Transitions.ENABLE_SHELL_TRANSITIONS &&
- DesktopModeStatus.canEnterDesktopMode(context)) {
+ if (
+ Transitions.ENABLE_SHELL_TRANSITIONS && DesktopModeStatus.canEnterDesktopMode(context)
+ ) {
shellInit.addInitCallback(this::onInit, this)
}
}
@@ -350,4 +351,4 @@
return this.type == WindowManager.TRANSIT_TO_FRONT &&
this.flags == WindowManager.TRANSIT_FLAG_IS_RECENTS
}
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
index f1a475a..bc27f34 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
@@ -20,9 +20,7 @@
import com.android.wm.shell.sysui.ShellCommandHandler
import java.io.PrintWriter
-/**
- * Handles the shell commands for the DesktopTasksController.
- */
+/** Handles the shell commands for the DesktopTasksController. */
class DesktopModeShellCommandHandler(private val controller: DesktopTasksController) :
ShellCommandHandler.ShellCommandActionHandler {
@@ -58,12 +56,13 @@
return false
}
- val taskId = try {
- args[1].toInt()
- } catch (e: NumberFormatException) {
- pw.println("Error: task id should be an integer")
- return false
- }
+ val taskId =
+ try {
+ args[1].toInt()
+ } catch (e: NumberFormatException) {
+ pw.println("Error: task id should be an integer")
+ return false
+ }
return controller.moveToDesktop(taskId, WindowContainerTransaction())
}
@@ -75,12 +74,13 @@
return false
}
- val taskId = try {
- args[1].toInt()
- } catch (e: NumberFormatException) {
- pw.println("Error: task id should be an integer")
- return false
- }
+ val taskId =
+ try {
+ args[1].toInt()
+ } catch (e: NumberFormatException) {
+ pw.println("Error: task id should be an integer")
+ return false
+ }
controller.moveToNextDisplay(taskId)
return true
@@ -92,4 +92,4 @@
pw.println("$prefix moveToNextDisplay <taskId> ")
pw.println("$prefix Move a task with given id to next display.")
}
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
index afc32b5..7d01580 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -29,13 +29,10 @@
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.util.KtProtoLog
import java.io.PrintWriter
-import java.util.ArrayList;
import java.util.concurrent.Executor
import java.util.function.Consumer
-/**
- * Keeps track of task data related to desktop mode.
- */
+/** Keeps track of task data related to desktop mode. */
class DesktopModeTaskRepository {
/** Task data that is tracked per display */
@@ -85,13 +82,8 @@
activeTasksListeners.add(activeTasksListener)
}
- /**
- * Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not.
- */
- fun addVisibleTasksListener(
- visibleTasksListener: VisibleTasksListener,
- executor: Executor
- ) {
+ /** Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not. */
+ fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) {
visibleTasksListeners[visibleTasksListener] = executor
displayData.keyIterator().forEach { displayId ->
val visibleTasksCount = getVisibleTaskCount(displayId)
@@ -113,9 +105,7 @@
}
}
- /**
- * Create a new merged region representative of all exclusion regions in all desktop tasks.
- */
+ /** Create a new merged region representative of all exclusion regions in all desktop tasks. */
private fun calculateDesktopExclusionRegion(): Region {
val desktopExclusionRegion = Region()
desktopExclusionRegions.valueIterator().forEach { taskExclusionRegion ->
@@ -124,16 +114,12 @@
return desktopExclusionRegion
}
- /**
- * Remove a previously registered [ActiveTasksListener]
- */
+ /** Remove a previously registered [ActiveTasksListener] */
fun removeActiveTasksListener(activeTasksListener: ActiveTasksListener) {
activeTasksListeners.remove(activeTasksListener)
}
- /**
- * Remove a previously registered [VisibleTasksListener]
- */
+ /** Remove a previously registered [VisibleTasksListener] */
fun removeVisibleTasksListener(visibleTasksListener: VisibleTasksListener) {
visibleTasksListeners.remove(visibleTasksListener)
}
@@ -183,18 +169,14 @@
return result
}
- /**
- * Check if a task with the given [taskId] was marked as an active task
- */
+ /** Check if a task with the given [taskId] was marked as an active task */
fun isActiveTask(taskId: Int): Boolean {
return displayData.valueIterator().asSequence().any { data ->
data.activeTasks.contains(taskId)
}
}
- /**
- * Whether a task is visible.
- */
+ /** Whether a task is visible. */
fun isVisibleTask(taskId: Int): Boolean {
return displayData.valueIterator().asSequence().any { data ->
data.visibleTasks.contains(taskId)
@@ -208,18 +190,14 @@
}
}
- /**
- * Check if a task with the given [taskId] is the only active task on its display
- */
+ /** Check if a task with the given [taskId] is the only active task on its display */
fun isOnlyActiveTask(taskId: Int): Boolean {
return displayData.valueIterator().asSequence().any { data ->
data.activeTasks.singleOrNull() == taskId
}
}
- /**
- * Get a set of the active tasks for given [displayId]
- */
+ /** Get a set of the active tasks for given [displayId] */
fun getActiveTasks(displayId: Int): ArraySet<Int> {
return ArraySet(displayData[displayId]?.activeTasks)
}
@@ -238,14 +216,12 @@
val activeTasks = getActiveTasks(displayId)
val allTasksInZOrder = getFreeformTasksInZOrder(displayId)
return activeTasks
- // Don't show already minimized Tasks
- .filter { taskId -> !isMinimizedTask(taskId) }
- .sortedBy { taskId -> allTasksInZOrder.indexOf(taskId) }
+ // Don't show already minimized Tasks
+ .filter { taskId -> !isMinimizedTask(taskId) }
+ .sortedBy { taskId -> allTasksInZOrder.indexOf(taskId) }
}
- /**
- * Get a list of freeform tasks, ordered from top-bottom (top at index 0).
- */
+ /** Get a list of freeform tasks, ordered from top-bottom (top at index 0). */
fun getFreeformTasksInZOrder(displayId: Int): ArrayList<Int> =
ArrayList(displayData[displayId]?.freeformTasksInZOrder ?: emptyList())
@@ -261,8 +237,10 @@
val otherDisplays = displayData.keyIterator().asSequence().filter { it != displayId }
for (otherDisplayId in otherDisplays) {
if (displayData[otherDisplayId].visibleTasks.remove(taskId)) {
- notifyVisibleTaskListeners(otherDisplayId,
- displayData[otherDisplayId].visibleTasks.size)
+ notifyVisibleTaskListeners(
+ otherDisplayId,
+ displayData[otherDisplayId].visibleTasks.size
+ )
}
}
} else if (displayId == INVALID_DISPLAY) {
@@ -309,9 +287,7 @@
}
}
- /**
- * Get number of tasks that are marked as visible on given [displayId]
- */
+ /** Get number of tasks that are marked as visible on given [displayId] */
fun getVisibleTaskCount(displayId: Int): Int {
KtProtoLog.d(
WM_SHELL_DESKTOP_MODE,
@@ -321,16 +297,15 @@
return displayData[displayId]?.visibleTasks?.size ?: 0
}
- /**
- * Add (or move if it already exists) the task to the top of the ordered list.
- */
- // TODO(b/342417921): Identify if there is additional checks needed to move tasks for
- // multi-display scenarios.
+ /** Add (or move if it already exists) the task to the top of the ordered list. */
+ // TODO(b/342417921): Identify if there is additional checks needed to move tasks for
+ // multi-display scenarios.
fun addOrMoveFreeformTaskToTop(displayId: Int, taskId: Int) {
KtProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: add or move task to top: display=%d, taskId=%d",
- displayId, taskId
+ displayId,
+ taskId
)
displayData[displayId]?.freeformTasksInZOrder?.remove(taskId)
displayData.getOrCreate(displayId).freeformTasksInZOrder.add(0, taskId)
@@ -339,29 +314,32 @@
/** Mark a Task as minimized. */
fun minimizeTask(displayId: Int, taskId: Int) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopModeTaskRepository: minimize Task: display=%d, task=%d",
- displayId, taskId)
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopModeTaskRepository: minimize Task: display=%d, task=%d",
+ displayId,
+ taskId
+ )
displayData.getOrCreate(displayId).minimizedTasks.add(taskId)
}
/** Mark a Task as non-minimized. */
fun unminimizeTask(displayId: Int, taskId: Int) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopModeTaskRepository: unminimize Task: display=%d, task=%d",
- displayId, taskId)
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopModeTaskRepository: unminimize Task: display=%d, task=%d",
+ displayId,
+ taskId
+ )
displayData[displayId]?.minimizedTasks?.remove(taskId)
}
- /**
- * Remove the task from the ordered list.
- */
+ /** Remove the task from the ordered list. */
fun removeFreeformTask(displayId: Int, taskId: Int) {
KtProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"DesktopTaskRepo: remove freeform task from ordered list: display=%d, taskId=%d",
- displayId, taskId
+ displayId,
+ taskId
)
displayData[displayId]?.freeformTasksInZOrder?.remove(taskId)
boundsBeforeMaximizeByTaskId.remove(taskId)
@@ -374,8 +352,7 @@
/**
* Updates the active desktop gesture exclusion regions; if desktopExclusionRegions has been
- * accepted by desktopGestureExclusionListener, it will be updated in the
- * appropriate classes.
+ * accepted by desktopGestureExclusionListener, it will be updated in the appropriate classes.
*/
fun updateTaskExclusionRegions(taskId: Int, taskExclusionRegions: Region) {
desktopExclusionRegions.put(taskId, taskExclusionRegions)
@@ -385,9 +362,9 @@
}
/**
- * Removes the desktop gesture exclusion region for the specified task; if exclusionRegion
- * has been accepted by desktopGestureExclusionListener, it will be updated in the
- * appropriate classes.
+ * Removes the desktop gesture exclusion region for the specified task; if exclusionRegion has
+ * been accepted by desktopGestureExclusionListener, it will be updated in the appropriate
+ * classes.
*/
fun removeExclusionRegion(taskId: Int) {
desktopExclusionRegions.delete(taskId)
@@ -396,16 +373,12 @@
}
}
- /**
- * Removes and returns the bounds saved before maximizing the given task.
- */
+ /** Removes and returns the bounds saved before maximizing the given task. */
fun removeBoundsBeforeMaximize(taskId: Int): Rect? {
return boundsBeforeMaximizeByTaskId.removeReturnOld(taskId)
}
- /**
- * Saves the bounds of the given task before maximizing.
- */
+ /** Saves the bounds of the given task before maximizing. */
fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) {
boundsBeforeMaximizeByTaskId.set(taskId, Rect(bounds))
}
@@ -424,7 +397,9 @@
pw.println("${prefix}Display $displayId:")
pw.println("${innerPrefix}activeTasks=${data.activeTasks.toDumpString()}")
pw.println("${innerPrefix}visibleTasks=${data.visibleTasks.toDumpString()}")
- pw.println("${innerPrefix}freeformTasksInZOrder=${data.freeformTasksInZOrder.toDumpString()}")
+ pw.println(
+ "${innerPrefix}freeformTasksInZOrder=${data.freeformTasksInZOrder.toDumpString()}"
+ )
}
}
@@ -432,9 +407,7 @@
* Defines interface for classes that can listen to changes for active tasks in desktop mode.
*/
interface ActiveTasksListener {
- /**
- * Called when the active tasks change in desktop mode.
- */
+ /** Called when the active tasks change in desktop mode. */
fun onActiveTasksChanged(displayId: Int) {}
}
@@ -442,9 +415,7 @@
* Defines interface for classes that can listen to changes for visible tasks in desktop mode.
*/
interface VisibleTasksListener {
- /**
- * Called when the desktop changes the number of visible freeform tasks.
- */
+ /** Called when the desktop changes the number of visible freeform tasks. */
fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
index aa11a7d..a9d4e5f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
@@ -24,11 +24,11 @@
import com.android.wm.shell.dagger.WMSingleton
import javax.inject.Inject
-/**
- * Log Aster UIEvents for desktop windowing mode.
- */
+/** Log Aster UIEvents for desktop windowing mode. */
@WMSingleton
-class DesktopModeUiEventLogger @Inject constructor(
+class DesktopModeUiEventLogger
+@Inject
+constructor(
private val mUiEventLogger: UiEventLogger,
private val mInstanceIdSequence: InstanceIdSequence
) {
@@ -47,16 +47,14 @@
mUiEventLogger.log(event, uid, packageName)
}
- /**
- * Retrieves a new instance id for a new interaction.
- */
+ /** Retrieves a new instance id for a new interaction. */
fun getNewInstanceId(): InstanceId = mInstanceIdSequence.newInstanceId()
/**
* Logs an event as part of a particular CUI, on a particular package.
*
* @param instanceId The id identifying an interaction, potentially taking place across multiple
- * surfaces. There should be a new id generated for each distinct CUI.
+ * surfaces. There should be a new id generated for each distinct CUI.
* @param uid The user id associated with the package the user is interacting with
* @param packageName The name of the package the user is interacting with
* @param event The event type to generate
@@ -75,20 +73,15 @@
}
companion object {
- /**
- * Enums for logging desktop windowing mode UiEvents.
- */
+ /** Enums for logging desktop windowing mode UiEvents. */
enum class DesktopUiEventEnum(private val mId: Int) : UiEventLogger.UiEventEnum {
@UiEvent(doc = "Resize the window in desktop windowing mode by dragging the edge")
DESKTOP_WINDOW_EDGE_DRAG_RESIZE(1721),
-
@UiEvent(doc = "Resize the window in desktop windowing mode by dragging the corner")
DESKTOP_WINDOW_CORNER_DRAG_RESIZE(1722),
-
@UiEvent(doc = "Tap on the window header maximize button in desktop windowing mode")
DESKTOP_WINDOW_MAXIMIZE_BUTTON_TAP(1723),
-
@UiEvent(doc = "Double tap on window header to maximize it in desktop windowing mode")
DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724);
@@ -97,4 +90,4 @@
private const val TAG = "DesktopModeUiEventLogger"
}
-}
\ No newline at end of file
+}
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 6da3741..217b1d3 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
@@ -28,13 +28,11 @@
import android.util.Size
import com.android.wm.shell.common.DisplayLayout
+val DESKTOP_MODE_INITIAL_BOUNDS_SCALE: Float =
+ SystemProperties.getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
-val DESKTOP_MODE_INITIAL_BOUNDS_SCALE: Float = SystemProperties
- .getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
-
-val DESKTOP_MODE_LANDSCAPE_APP_PADDING: Int = SystemProperties
- .getInt("persist.wm.debug.desktop_mode_landscape_app_padding", 25)
-
+val DESKTOP_MODE_LANDSCAPE_APP_PADDING: Int =
+ SystemProperties.getInt("persist.wm.debug.desktop_mode_landscape_app_padding", 25)
/**
* Calculates the initial bounds required for an application to fill a scale of the display bounds
@@ -52,51 +50,53 @@
val idealSize = calculateIdealSize(screenBounds, scale)
// If no top activity exists, apps fullscreen bounds and aspect ratio cannot be calculated.
// Instead default to the desired initial bounds.
- val topActivityInfo = taskInfo.topActivityInfo
- ?: return positionInScreen(idealSize, screenBounds)
+ val topActivityInfo =
+ taskInfo.topActivityInfo ?: return positionInScreen(idealSize, screenBounds)
- val initialSize: Size = when (taskInfo.configuration.orientation) {
- ORIENTATION_LANDSCAPE -> {
- if (taskInfo.isResizeable) {
- if (isFixedOrientationPortrait(topActivityInfo.screenOrientation)) {
- // Respect apps fullscreen width
- Size(taskInfo.appCompatTaskInfo.topActivityLetterboxWidth, idealSize.height)
+ val initialSize: Size =
+ when (taskInfo.configuration.orientation) {
+ ORIENTATION_LANDSCAPE -> {
+ if (taskInfo.isResizeable) {
+ if (isFixedOrientationPortrait(topActivityInfo.screenOrientation)) {
+ // Respect apps fullscreen width
+ Size(taskInfo.appCompatTaskInfo.topActivityLetterboxWidth, idealSize.height)
+ } else {
+ idealSize
+ }
} else {
- idealSize
- }
- } else {
- maximumSizeMaintainingAspectRatio(taskInfo, idealSize,
- appAspectRatio)
- }
- }
- ORIENTATION_PORTRAIT -> {
- val customPortraitWidthForLandscapeApp = screenBounds.width() -
- (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2)
- if (taskInfo.isResizeable) {
- if (isFixedOrientationLandscape(topActivityInfo.screenOrientation)) {
- // Respect apps fullscreen height and apply custom app width
- Size(customPortraitWidthForLandscapeApp,
- taskInfo.appCompatTaskInfo.topActivityLetterboxHeight)
- } else {
- idealSize
- }
- } else {
- if (isFixedOrientationLandscape(topActivityInfo.screenOrientation)) {
- // Apply custom app width and calculate maximum size
- maximumSizeMaintainingAspectRatio(
- taskInfo,
- Size(customPortraitWidthForLandscapeApp, idealSize.height),
- appAspectRatio)
- } else {
- maximumSizeMaintainingAspectRatio(taskInfo, idealSize,
- appAspectRatio)
+ maximumSizeMaintainingAspectRatio(taskInfo, idealSize, appAspectRatio)
}
}
+ ORIENTATION_PORTRAIT -> {
+ val customPortraitWidthForLandscapeApp =
+ screenBounds.width() - (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2)
+ if (taskInfo.isResizeable) {
+ if (isFixedOrientationLandscape(topActivityInfo.screenOrientation)) {
+ // Respect apps fullscreen height and apply custom app width
+ Size(
+ customPortraitWidthForLandscapeApp,
+ taskInfo.appCompatTaskInfo.topActivityLetterboxHeight
+ )
+ } else {
+ idealSize
+ }
+ } else {
+ if (isFixedOrientationLandscape(topActivityInfo.screenOrientation)) {
+ // Apply custom app width and calculate maximum size
+ maximumSizeMaintainingAspectRatio(
+ taskInfo,
+ Size(customPortraitWidthForLandscapeApp, idealSize.height),
+ appAspectRatio
+ )
+ } else {
+ maximumSizeMaintainingAspectRatio(taskInfo, idealSize, appAspectRatio)
+ }
+ }
+ }
+ else -> {
+ idealSize
+ }
}
- else -> {
- idealSize
- }
- }
return positionInScreen(initialSize, screenBounds)
}
@@ -136,19 +136,17 @@
return Size(finalWidth, finalHeight)
}
-/**
- * Calculates the aspect ratio of an activity from its fullscreen bounds.
- */
+/** Calculates the aspect ratio of an activity from its fullscreen bounds. */
private fun calculateAspectRatio(taskInfo: RunningTaskInfo): Float {
if (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed) {
val appLetterboxWidth = taskInfo.appCompatTaskInfo.topActivityLetterboxWidth
val appLetterboxHeight = taskInfo.appCompatTaskInfo.topActivityLetterboxHeight
return maxOf(appLetterboxWidth, appLetterboxHeight) /
- minOf(appLetterboxWidth, appLetterboxHeight).toFloat()
+ minOf(appLetterboxWidth, appLetterboxHeight).toFloat()
}
val appBounds = taskInfo.configuration.windowConfiguration.appBounds ?: return 1f
return maxOf(appBounds.height(), appBounds.width()) /
- minOf(appBounds.height(), appBounds.width()).toFloat()
+ minOf(appBounds.height(), appBounds.width()).toFloat()
}
/**
@@ -161,13 +159,15 @@
return Size(width, height)
}
-/**
- * Adjusts bounds to be positioned in the middle of the screen.
- */
+/** Adjusts bounds to be positioned in the middle of the screen. */
private fun positionInScreen(desiredSize: Size, screenBounds: Rect): Rect {
// TODO(b/325240051): Position apps with bottom heavy offset
val heightOffset = (screenBounds.height() - desiredSize.height) / 2
val widthOffset = (screenBounds.width() - desiredSize.width) / 2
- return Rect(widthOffset, heightOffset,
- desiredSize.width + widthOffset, desiredSize.height + heightOffset)
+ return Rect(
+ widthOffset,
+ heightOffset,
+ desiredSize.width + widthOffset,
+ desiredSize.height + heightOffset
+ )
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 2e40ba7..38db1eb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -17,10 +17,10 @@
package com.android.wm.shell.desktopmode;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -186,7 +186,7 @@
// In freeform, keep the top corners clear.
int transitionHeight = windowingMode == WINDOWING_MODE_FREEFORM
? mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) :
+ com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) :
-captionHeight;
region.union(new Rect(0, transitionHeight, transitionEdgeWidth, layout.height()));
return region;
@@ -315,10 +315,11 @@
private static final float INDICATOR_FINAL_OPACITY = 0.35f;
private static final int MAXIMUM_OPACITY = 255;
- /** Determines how this animator will interact with the view's alpha:
- * Fade in, fade out, or no change to alpha
+ /**
+ * Determines how this animator will interact with the view's alpha:
+ * Fade in, fade out, or no change to alpha
*/
- private enum AlphaAnimType{
+ private enum AlphaAnimType {
ALPHA_FADE_IN_ANIM, ALPHA_FADE_OUT_ANIM, ALPHA_NO_CHANGE_ANIM
}
@@ -365,10 +366,10 @@
* Create animator for visual indicator changing type (i.e., fullscreen to freeform,
* freeform to split, etc.)
*
- * @param view the view for this indicator
+ * @param view the view for this indicator
* @param displayLayout information about the display the transitioning task is currently on
- * @param origType the original indicator type
- * @param newType the new indicator type
+ * @param origType the original indicator type
+ * @param newType the new indicator type
*/
private static VisualIndicatorAnimator animateIndicatorType(@NonNull View view,
@NonNull DisplayLayout displayLayout, IndicatorType origType,
@@ -469,7 +470,7 @@
*/
private static Rect getMaxBounds(Rect startBounds) {
return new Rect((int) (startBounds.left
- - (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * startBounds.width())),
+ - (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * startBounds.width())),
(int) (startBounds.top
- (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * startBounds.height())),
(int) (startBounds.right
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 e5bf53a..6e45397 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
@@ -97,69 +97,74 @@
/** Handles moving tasks in and out of desktop */
class DesktopTasksController(
- private val context: Context,
- shellInit: ShellInit,
- private val shellCommandHandler: ShellCommandHandler,
- private val shellController: ShellController,
- private val displayController: DisplayController,
- private val shellTaskOrganizer: ShellTaskOrganizer,
- private val syncQueue: SyncTransactionQueue,
- private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
- private val dragAndDropController: DragAndDropController,
- private val transitions: Transitions,
- private val enterDesktopTaskTransitionHandler: EnterDesktopTaskTransitionHandler,
- private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
- private val toggleResizeDesktopTaskTransitionHandler:
- ToggleResizeDesktopTaskTransitionHandler,
- private val dragToDesktopTransitionHandler: DragToDesktopTransitionHandler,
- private val desktopModeTaskRepository: DesktopModeTaskRepository,
- private val desktopModeLoggerTransitionObserver: DesktopModeLoggerTransitionObserver,
- private val launchAdjacentController: LaunchAdjacentController,
- private val recentsTransitionHandler: RecentsTransitionHandler,
- private val multiInstanceHelper: MultiInstanceHelper,
- @ShellMainThread private val mainExecutor: ShellExecutor,
- private val desktopTasksLimiter: Optional<DesktopTasksLimiter>,
-) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler,
+ private val context: Context,
+ shellInit: ShellInit,
+ private val shellCommandHandler: ShellCommandHandler,
+ private val shellController: ShellController,
+ private val displayController: DisplayController,
+ private val shellTaskOrganizer: ShellTaskOrganizer,
+ private val syncQueue: SyncTransactionQueue,
+ private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
+ private val dragAndDropController: DragAndDropController,
+ private val transitions: Transitions,
+ private val enterDesktopTaskTransitionHandler: EnterDesktopTaskTransitionHandler,
+ private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
+ private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
+ private val dragToDesktopTransitionHandler: DragToDesktopTransitionHandler,
+ private val desktopModeTaskRepository: DesktopModeTaskRepository,
+ private val desktopModeLoggerTransitionObserver: DesktopModeLoggerTransitionObserver,
+ private val launchAdjacentController: LaunchAdjacentController,
+ private val recentsTransitionHandler: RecentsTransitionHandler,
+ private val multiInstanceHelper: MultiInstanceHelper,
+ @ShellMainThread private val mainExecutor: ShellExecutor,
+ private val desktopTasksLimiter: Optional<DesktopTasksLimiter>,
+) :
+ RemoteCallable<DesktopTasksController>,
+ Transitions.TransitionHandler,
DragAndDropController.DragAndDropListener {
private val desktopMode: DesktopModeImpl
private var visualIndicator: DesktopModeVisualIndicator? = null
private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler =
DesktopModeShellCommandHandler(this)
- private val mOnAnimationFinishedCallback = Consumer<SurfaceControl.Transaction> {
- t: SurfaceControl.Transaction ->
- visualIndicator?.releaseVisualIndicator(t)
- visualIndicator = null
- }
- private val taskVisibilityListener = object : VisibleTasksListener {
- override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
- launchAdjacentController.launchAdjacentEnabled = visibleTasksCount == 0
- }
- }
- private val dragToDesktopStateListener = object : DragToDesktopStateListener {
- override fun onCommitToDesktopAnimationStart(tx: SurfaceControl.Transaction) {
- removeVisualIndicator(tx)
- }
-
- override fun onCancelToDesktopAnimationEnd(tx: SurfaceControl.Transaction) {
- removeVisualIndicator(tx)
- }
-
- private fun removeVisualIndicator(tx: SurfaceControl.Transaction) {
- visualIndicator?.releaseVisualIndicator(tx)
+ private val mOnAnimationFinishedCallback =
+ Consumer<SurfaceControl.Transaction> { t: SurfaceControl.Transaction ->
+ visualIndicator?.releaseVisualIndicator(t)
visualIndicator = null
}
- }
+ private val taskVisibilityListener =
+ object : VisibleTasksListener {
+ override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
+ launchAdjacentController.launchAdjacentEnabled = visibleTasksCount == 0
+ }
+ }
+ private val dragToDesktopStateListener =
+ object : DragToDesktopStateListener {
+ override fun onCommitToDesktopAnimationStart(tx: SurfaceControl.Transaction) {
+ removeVisualIndicator(tx)
+ }
+
+ override fun onCancelToDesktopAnimationEnd(tx: SurfaceControl.Transaction) {
+ removeVisualIndicator(tx)
+ }
+
+ private fun removeVisualIndicator(tx: SurfaceControl.Transaction) {
+ visualIndicator?.releaseVisualIndicator(tx)
+ visualIndicator = null
+ }
+ }
private val transitionAreaHeight
- get() = context.resources.getDimensionPixelSize(
+ get() =
+ context.resources.getDimensionPixelSize(
com.android.wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height
- )
+ )
private val transitionAreaWidth
- get() = context.resources.getDimensionPixelSize(
- com.android.wm.shell.R.dimen.desktop_mode_transition_area_width
- )
+ get() =
+ context.resources.getDimensionPixelSize(
+ com.android.wm.shell.R.dimen.desktop_mode_transition_area_width
+ )
/** Task id of the task currently being dragged from fullscreen/split. */
val draggingTaskId
@@ -178,11 +183,7 @@
private fun onInit() {
KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
shellCommandHandler.addDumpCallback(this::dump, this)
- shellCommandHandler.addCommandCallback(
- "desktopmode",
- desktopModeShellCommandHandler,
- this
- )
+ shellCommandHandler.addCommandCallback("desktopmode", desktopModeShellCommandHandler, this)
shellController.addExternalInterface(
ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE,
{ createExternalInterface() },
@@ -232,9 +233,10 @@
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
// TODO(b/309014605): ensure remote transition is supplied once state is introduced
val transitionType = if (remoteTransition == null) TRANSIT_NONE else TRANSIT_TO_FRONT
- val handler = remoteTransition?.let {
- OneShotRemoteHandler(transitions.mainExecutor, remoteTransition)
- }
+ val handler =
+ remoteTransition?.let {
+ OneShotRemoteHandler(transitions.mainExecutor, remoteTransition)
+ }
transitions.startTransition(transitionType, wct, handler).also { t ->
handler?.setTransition(t)
}
@@ -253,9 +255,9 @@
val allFocusedTasks =
shellTaskOrganizer.getRunningTasks(displayId).filter { taskInfo ->
taskInfo.isFocused &&
- (taskInfo.windowingMode == WINDOWING_MODE_FULLSCREEN ||
- taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW) &&
- taskInfo.activityType != ACTIVITY_TYPE_HOME
+ (taskInfo.windowingMode == WINDOWING_MODE_FULLSCREEN ||
+ taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW) &&
+ taskInfo.activityType != ACTIVITY_TYPE_HOME
}
if (allFocusedTasks.isNotEmpty()) {
when (allFocusedTasks.size) {
@@ -278,7 +280,7 @@
KtProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: Cannot enter desktop, expected less " +
- "than 3 focused tasks but found %d",
+ "than 3 focused tasks but found %d",
allFocusedTasks.size
)
}
@@ -288,27 +290,24 @@
/** Move a task with given `taskId` to desktop */
fun moveToDesktop(
- taskId: Int,
- wct: WindowContainerTransaction = WindowContainerTransaction()
+ taskId: Int,
+ wct: WindowContainerTransaction = WindowContainerTransaction()
): Boolean {
- shellTaskOrganizer.getRunningTaskInfo(taskId)?.let {
- task -> moveToDesktop(task, wct)
- } ?: return false
+ shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveToDesktop(task, wct) }
+ ?: return false
return true
}
- /**
- * Move a task to desktop
- */
+ /** Move a task to desktop */
fun moveToDesktop(
- task: RunningTaskInfo,
- wct: WindowContainerTransaction = WindowContainerTransaction()
+ task: RunningTaskInfo,
+ wct: WindowContainerTransaction = WindowContainerTransaction()
) {
if (!DesktopModeStatus.canEnterDesktopMode(context)) {
KtProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: Cannot enter desktop, " +
- "display does not meet minimum size requirements"
+ "display does not meet minimum size requirements"
)
return
}
@@ -316,7 +315,7 @@
KtProtoLog.w(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: Cannot enter desktop, " +
- "translucent top activity found. This is likely a modal dialog."
+ "translucent top activity found. This is likely a modal dialog."
)
return
}
@@ -328,7 +327,7 @@
exitSplitIfApplicable(wct, task)
// Bring other apps to front first
val taskToMinimize =
- bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
+ bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
addMoveToDesktopChanges(wct, task)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
@@ -340,21 +339,21 @@
}
/**
- * The first part of the animated drag to desktop transition. This is
- * followed with a call to [finalizeDragToDesktop] or [cancelDragToDesktop].
+ * The first part of the animated drag to desktop transition. This is followed with a call to
+ * [finalizeDragToDesktop] or [cancelDragToDesktop].
*/
fun startDragToDesktop(
- taskInfo: RunningTaskInfo,
- dragToDesktopValueAnimator: MoveToDesktopAnimator,
+ taskInfo: RunningTaskInfo,
+ dragToDesktopValueAnimator: MoveToDesktopAnimator,
) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: startDragToDesktop taskId=%d",
- taskInfo.taskId
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: startDragToDesktop taskId=%d",
+ taskInfo.taskId
)
dragToDesktopTransitionHandler.startDragToDesktopTransition(
- taskInfo.taskId,
- dragToDesktopValueAnimator
+ taskInfo.taskId,
+ dragToDesktopValueAnimator
)
}
@@ -364,16 +363,15 @@
*/
private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo, freeformBounds: Rect) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: finalizeDragToDesktop taskId=%d",
- taskInfo.taskId
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: finalizeDragToDesktop taskId=%d",
+ taskInfo.taskId
)
val wct = WindowContainerTransaction()
exitSplitIfApplicable(wct, taskInfo)
moveHomeTaskToFront(wct)
val taskToMinimize =
- bringDesktopAppsToFrontBeforeShowingNewTask(
- taskInfo.displayId, wct, taskInfo.taskId)
+ bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
addMoveToDesktopChanges(wct, taskInfo)
wct.setBounds(taskInfo.token, freeformBounds)
val transition = dragToDesktopTransitionHandler.finishDragToDesktopTransition(wct)
@@ -381,9 +379,9 @@
}
/**
- * Perform needed cleanup transaction once animation is complete. Bounds need to be set
- * here instead of initial wct to both avoid flicker and to have task bounds to use for
- * the staging animation.
+ * Perform needed cleanup transaction once animation is complete. Bounds need to be set here
+ * instead of initial wct to both avoid flicker and to have task bounds to use for the staging
+ * animation.
*
* @param taskInfo task entering split that requires a bounds update
*/
@@ -395,16 +393,13 @@
}
/**
- * Perform clean up of the desktop wallpaper activity if the closed window task is
- * the last active task.
+ * Perform clean up of the desktop wallpaper activity if the closed window task is the last
+ * active task.
*
* @param wct transaction to modify if the last active task is closed
* @param taskId task id of the window that's being closed
*/
- fun onDesktopWindowClose(
- wct: WindowContainerTransaction,
- taskId: Int
- ) {
+ fun onDesktopWindowClose(wct: WindowContainerTransaction, taskId: Int) {
if (desktopModeTaskRepository.isOnlyActiveTask(taskId)) {
removeWallpaperActivity(wct)
}
@@ -419,8 +414,9 @@
/** Enter fullscreen by moving the focused freeform task in given `displayId` to fullscreen. */
fun enterFullscreen(displayId: Int) {
- getFocusedFreeformTask(displayId)
- ?.let { moveToFullscreenWithAnimation(it, it.positionInParent) }
+ getFocusedFreeformTask(displayId)?.let {
+ moveToFullscreenWithAnimation(it, it.positionInParent)
+ }
}
/** Move a desktop app to split screen. */
@@ -449,8 +445,7 @@
splitScreenController.getStageOfTask(taskInfo.taskId),
EXIT_REASON_DESKTOP_MODE
)
- splitScreenController.transitionHandler
- ?.onSplitToDesktop()
+ splitScreenController.transitionHandler?.onSplitToDesktop()
}
}
@@ -469,16 +464,16 @@
private fun moveToFullscreenWithAnimation(task: RunningTaskInfo, position: Point) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: moveToFullscreen with animation taskId=%d",
- task.taskId
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: moveToFullscreen with animation taskId=%d",
+ task.taskId
)
val wct = WindowContainerTransaction()
addMoveToFullscreenChanges(wct, task)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
exitDesktopTaskTransitionHandler.startTransition(
- Transitions.TRANSIT_EXIT_DESKTOP_MODE,
+ Transitions.TRANSIT_EXIT_DESKTOP_MODE,
wct,
position,
mOnAnimationFinishedCallback
@@ -517,12 +512,12 @@
* Move task to the next display.
*
* Queries all current known display ids and sorts them in ascending order. Then iterates
- * through the list and looks for the display id that is larger than the display id for
- * the passed in task. If a display with a higher id is not found, iterates through the list and
+ * through the list and looks for the display id that is larger than the display id for the
+ * passed in task. If a display with a higher id is not found, iterates through the list and
* finds the first display id that is not the display id for the passed in task.
*
- * If a display matching the above criteria is found, re-parents the task to that display.
- * No-op if no such display is found.
+ * If a display matching the above criteria is found, re-parents the task to that display. No-op
+ * if no such display is found.
*/
fun moveToNextDisplay(taskId: Int) {
val task = shellTaskOrganizer.getRunningTaskInfo(taskId)
@@ -533,7 +528,7 @@
KtProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"moveToNextDisplay: taskId=%d taskDisplayId=%d",
- taskId,
+ taskId,
task.displayId
)
@@ -560,7 +555,7 @@
KtProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"moveToDisplay: taskId=%d displayId=%d",
- task.taskId,
+ task.taskId,
displayId
)
@@ -585,9 +580,9 @@
}
/**
- * Quick-resizes a desktop task, toggling between a fullscreen state (represented by the
- * stable bounds) and a free floating state (either the last saved bounds if available or the
- * default bounds otherwise).
+ * Quick-resizes a desktop task, toggling between a fullscreen state (represented by the stable
+ * bounds) and a free floating state (either the last saved bounds if available or the default
+ * bounds otherwise).
*/
fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) {
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
@@ -600,11 +595,11 @@
// before the task was toggled to stable bounds were saved, toggle the task to those
// bounds. Otherwise, toggle to the default bounds.
val taskBoundsBeforeMaximize =
- desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId)
+ desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId)
if (taskBoundsBeforeMaximize != null) {
destinationBounds.set(taskBoundsBeforeMaximize)
} else {
- if (Flags.enableWindowingDynamicInitialBounds()){
+ if (Flags.enableWindowingDynamicInitialBounds()) {
destinationBounds.set(calculateInitialBounds(displayLayout, taskInfo))
} else {
destinationBounds.set(getDefaultDesktopTaskBounds(displayLayout))
@@ -650,8 +645,12 @@
val desiredHeight = (displayLayout.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE).toInt()
val heightOffset = (displayLayout.height() - desiredHeight) / 2
val widthOffset = (displayLayout.width() - desiredWidth) / 2
- return Rect(widthOffset, heightOffset,
- desiredWidth + widthOffset, desiredHeight + heightOffset)
+ return Rect(
+ widthOffset,
+ heightOffset,
+ desiredWidth + widthOffset,
+ desiredHeight + heightOffset
+ )
}
private fun getSnapBounds(taskInfo: RunningTaskInfo, position: SnapPosition): Rect {
@@ -693,19 +692,21 @@
}
private fun bringDesktopAppsToFrontBeforeShowingNewTask(
- displayId: Int,
- wct: WindowContainerTransaction,
- newTaskIdInFront: Int
+ displayId: Int,
+ wct: WindowContainerTransaction,
+ newTaskIdInFront: Int
): RunningTaskInfo? = bringDesktopAppsToFront(displayId, wct, newTaskIdInFront)
private fun bringDesktopAppsToFront(
- displayId: Int,
- wct: WindowContainerTransaction,
- newTaskIdInFront: Int? = null
+ displayId: Int,
+ wct: WindowContainerTransaction,
+ newTaskIdInFront: Int? = null
): RunningTaskInfo? {
- KtProtoLog.v(WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: bringDesktopAppsToFront, newTaskIdInFront=%s",
- newTaskIdInFront ?: "null")
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: bringDesktopAppsToFront, newTaskIdInFront=%s",
+ newTaskIdInFront ?: "null"
+ )
if (Flags.enableDesktopWindowingWallpaperActivity()) {
// Add translucent wallpaper activity to show the wallpaper underneath
@@ -716,19 +717,25 @@
}
val nonMinimizedTasksOrderedFrontToBack =
- desktopModeTaskRepository.getActiveNonMinimizedTasksOrderedFrontToBack(displayId)
+ desktopModeTaskRepository.getActiveNonMinimizedTasksOrderedFrontToBack(displayId)
// If we're adding a new Task we might need to minimize an old one
val taskToMinimize: RunningTaskInfo? =
- if (newTaskIdInFront != null && desktopTasksLimiter.isPresent) {
- desktopTasksLimiter.get().getTaskToMinimizeIfNeeded(
- nonMinimizedTasksOrderedFrontToBack, newTaskIdInFront)
- } else { null }
+ if (newTaskIdInFront != null && desktopTasksLimiter.isPresent) {
+ desktopTasksLimiter
+ .get()
+ .getTaskToMinimizeIfNeeded(
+ nonMinimizedTasksOrderedFrontToBack,
+ newTaskIdInFront
+ )
+ } else {
+ null
+ }
nonMinimizedTasksOrderedFrontToBack
- // If there is a Task to minimize, let it stay behind the Home Task
- .filter { taskId -> taskId != taskToMinimize?.taskId }
- .mapNotNull { taskId -> shellTaskOrganizer.getRunningTaskInfo(taskId) }
- .reversed() // Start from the back so the front task is brought forward last
- .forEach { task -> wct.reorder(task.token, true /* onTop */) }
+ // If there is a Task to minimize, let it stay behind the Home Task
+ .filter { taskId -> taskId != taskToMinimize?.taskId }
+ .mapNotNull { taskId -> shellTaskOrganizer.getRunningTaskInfo(taskId) }
+ .reversed() // Start from the back so the front task is brought forward last
+ .forEach { task -> wct.reorder(task.token, true /* onTop */) }
return taskToMinimize
}
@@ -742,13 +749,19 @@
private fun addWallpaperActivity(wct: WindowContainerTransaction) {
KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: addWallpaper")
val intent = Intent(context, DesktopWallpaperActivity::class.java)
- val options = ActivityOptions.makeBasic().apply {
- isPendingIntentBackgroundActivityLaunchAllowedByPermission = true
- pendingIntentBackgroundActivityStartMode =
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
- }
- val pendingIntent = PendingIntent.getActivity(context, /* requestCode = */ 0, intent,
- PendingIntent.FLAG_IMMUTABLE)
+ val options =
+ ActivityOptions.makeBasic().apply {
+ isPendingIntentBackgroundActivityLaunchAllowedByPermission = true
+ pendingIntentBackgroundActivityStartMode =
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ }
+ val pendingIntent =
+ PendingIntent.getActivity(
+ context,
+ /* requestCode = */ 0,
+ intent,
+ PendingIntent.FLAG_IMMUTABLE
+ )
wct.sendPendingIntent(pendingIntent, intent, options.toBundle())
}
@@ -807,8 +820,7 @@
false
}
// Handle back navigation for the last window if wallpaper available
- shouldRemoveWallpaper(request) ->
- true
+ shouldRemoveWallpaper(request) -> true
// Only handle open or to front transitions
request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> {
reason = "transition type not handled (${request.type})"
@@ -826,7 +838,7 @@
}
// Only handle fullscreen or freeform tasks
triggerTask.windowingMode != WINDOWING_MODE_FULLSCREEN &&
- triggerTask.windowingMode != WINDOWING_MODE_FREEFORM -> {
+ triggerTask.windowingMode != WINDOWING_MODE_FREEFORM -> {
reason = "windowingMode not handled (${triggerTask.windowingMode})"
false
}
@@ -836,31 +848,32 @@
if (!shouldHandleRequest) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: skipping handleRequest reason=%s",
- reason
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: skipping handleRequest reason=%s",
+ reason
)
return null
}
- val result = triggerTask?.let { task ->
- when {
- request.type == TRANSIT_TO_BACK -> handleBackNavigation(task)
- // Check if the task has a top transparent activity
- shouldLaunchAsModal(task) -> handleTransparentTaskLaunch(task)
- // Check if fullscreen task should be updated
- task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
- // Check if freeform task should be updated
- task.isFreeform -> handleFreeformTaskLaunch(task, transition)
- else -> {
- null
+ val result =
+ triggerTask?.let { task ->
+ when {
+ request.type == TRANSIT_TO_BACK -> handleBackNavigation(task)
+ // Check if the task has a top transparent activity
+ shouldLaunchAsModal(task) -> handleTransparentTaskLaunch(task)
+ // Check if fullscreen task should be updated
+ task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
+ // Check if freeform task should be updated
+ task.isFreeform -> handleFreeformTaskLaunch(task, transition)
+ else -> {
+ null
+ }
}
}
- }
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: handleRequest result=%s",
- result ?: "null"
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: handleRequest result=%s",
+ result ?: "null"
)
return result
}
@@ -870,18 +883,15 @@
* This is intended to be used when desktop mode is part of another animation but isn't, itself,
* animating.
*/
- fun syncSurfaceState(
- info: TransitionInfo,
- finishTransaction: SurfaceControl.Transaction
- ) {
+ fun syncSurfaceState(info: TransitionInfo, finishTransaction: SurfaceControl.Transaction) {
// Add rounded corners to freeform windows
if (!DesktopModeStatus.useRoundedCorners()) {
return
}
val cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
info.changes
- .filter { it.taskInfo?.windowingMode == WINDOWING_MODE_FREEFORM }
- .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
+ .filter { it.taskInfo?.windowingMode == WINDOWING_MODE_FREEFORM }
+ .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
}
private fun shouldLaunchAsModal(task: TaskInfo) =
@@ -889,23 +899,23 @@
private fun shouldRemoveWallpaper(request: TransitionRequestInfo): Boolean {
return Flags.enableDesktopWindowingWallpaperActivity() &&
- request.type == TRANSIT_TO_BACK &&
- request.triggerTask?.let { task ->
- desktopModeTaskRepository.isOnlyActiveTask(task.taskId)
- } ?: false
+ request.type == TRANSIT_TO_BACK &&
+ request.triggerTask?.let { task ->
+ desktopModeTaskRepository.isOnlyActiveTask(task.taskId)
+ } ?: false
}
private fun handleFreeformTaskLaunch(
- task: RunningTaskInfo,
- transition: IBinder
+ task: RunningTaskInfo,
+ transition: IBinder
): WindowContainerTransaction? {
KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFreeformTaskLaunch")
if (!desktopModeTaskRepository.isDesktopModeShowing(task.displayId)) {
KtProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: switch freeform task to fullscreen oon transition" +
- " taskId=%d",
- task.taskId
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: switch freeform task to fullscreen oon transition" +
+ " taskId=%d",
+ task.taskId
)
return WindowContainerTransaction().also { wct ->
bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
@@ -927,16 +937,16 @@
}
private fun handleFullscreenTaskLaunch(
- task: RunningTaskInfo,
- transition: IBinder
+ task: RunningTaskInfo,
+ transition: IBinder
): WindowContainerTransaction? {
KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFullscreenTaskLaunch")
if (desktopModeTaskRepository.isDesktopModeShowing(task.displayId)) {
KtProtoLog.d(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: switch fullscreen task to freeform on transition" +
- " taskId=%d",
- task.taskId
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: switch fullscreen task to freeform on transition" +
+ " taskId=%d",
+ task.taskId
)
return WindowContainerTransaction().also { wct ->
addMoveToDesktopChanges(wct, task)
@@ -952,21 +962,18 @@
// Always launch transparent tasks in fullscreen.
private fun handleTransparentTaskLaunch(task: RunningTaskInfo): WindowContainerTransaction? {
// Already fullscreen, no-op.
- if (task.isFullscreen)
- return null
- return WindowContainerTransaction().also { wct ->
- addMoveToFullscreenChanges(wct, task)
- }
+ if (task.isFullscreen) return null
+ return WindowContainerTransaction().also { wct -> addMoveToFullscreenChanges(wct, task) }
}
/** Handle back navigation by removing wallpaper activity if it's the last active task */
private fun handleBackNavigation(task: RunningTaskInfo): WindowContainerTransaction? {
- if (desktopModeTaskRepository.isOnlyActiveTask(task.taskId) &&
- desktopModeTaskRepository.wallpaperActivityToken != null) {
+ if (
+ desktopModeTaskRepository.isOnlyActiveTask(task.taskId) &&
+ desktopModeTaskRepository.wallpaperActivityToken != null
+ ) {
// Remove wallpaper activity when the last active task is removed
- return WindowContainerTransaction().also { wct ->
- removeWallpaperActivity(wct)
- }
+ return WindowContainerTransaction().also { wct -> removeWallpaperActivity(wct) }
} else {
return null
}
@@ -979,12 +986,13 @@
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!!
val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
- val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FREEFORM) {
- // Display windowing is freeform, set to undefined and inherit it
- WINDOWING_MODE_UNDEFINED
- } else {
- WINDOWING_MODE_FREEFORM
- }
+ val targetWindowingMode =
+ if (tdaWindowingMode == WINDOWING_MODE_FREEFORM) {
+ // Display windowing is freeform, set to undefined and inherit it
+ WINDOWING_MODE_UNDEFINED
+ } else {
+ WINDOWING_MODE_FREEFORM
+ }
if (Flags.enableWindowingDynamicInitialBounds()) {
wct.setBounds(taskInfo.token, calculateInitialBounds(displayLayout, taskInfo))
}
@@ -1001,12 +1009,13 @@
) {
val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!!
val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
- val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FULLSCREEN) {
- // Display windowing is fullscreen, set to undefined and inherit it
- WINDOWING_MODE_UNDEFINED
- } else {
- WINDOWING_MODE_FULLSCREEN
- }
+ val targetWindowingMode =
+ if (tdaWindowingMode == WINDOWING_MODE_FULLSCREEN) {
+ // Display windowing is fullscreen, set to undefined and inherit it
+ WINDOWING_MODE_UNDEFINED
+ } else {
+ WINDOWING_MODE_FULLSCREEN
+ }
wct.setWindowingMode(taskInfo.token, targetWindowingMode)
wct.setBounds(taskInfo.token, Rect())
if (isDesktopDensityOverrideSet()) {
@@ -1018,10 +1027,7 @@
* Adds split screen changes to a transaction. Note that bounds are not reset here due to
* animation; see {@link onDesktopSplitSelectAnimComplete}
*/
- private fun addMoveToSplitChanges(
- wct: WindowContainerTransaction,
- taskInfo: RunningTaskInfo
- ) {
+ private fun addMoveToSplitChanges(wct: WindowContainerTransaction, taskInfo: RunningTaskInfo) {
// This windowing mode is to get the transition animation started; once we complete
// split select, we will change windowing mode to undefined and inherit from split stage.
// Going to undefined here causes task to flicker to the top left.
@@ -1034,38 +1040,35 @@
/** Returns the ID of the Task that will be minimized, or null if no task will be minimized. */
private fun addAndGetMinimizeChangesIfNeeded(
- displayId: Int,
- wct: WindowContainerTransaction,
- newTaskInfo: RunningTaskInfo
+ displayId: Int,
+ wct: WindowContainerTransaction,
+ newTaskInfo: RunningTaskInfo
): RunningTaskInfo? {
if (!desktopTasksLimiter.isPresent) return null
- return desktopTasksLimiter.get().addAndGetMinimizeTaskChangesIfNeeded(
- displayId, wct, newTaskInfo)
+ return desktopTasksLimiter
+ .get()
+ .addAndGetMinimizeTaskChangesIfNeeded(displayId, wct, newTaskInfo)
}
private fun addPendingMinimizeTransition(
- transition: IBinder,
- taskToMinimize: RunningTaskInfo?
+ transition: IBinder,
+ taskToMinimize: RunningTaskInfo?
) {
if (taskToMinimize == null) return
desktopTasksLimiter.ifPresent {
- it.addPendingMinimizeChange(
- transition, taskToMinimize.displayId, taskToMinimize.taskId)
+ it.addPendingMinimizeChange(transition, taskToMinimize.displayId, taskToMinimize.taskId)
}
}
/** Enter split by using the focused desktop task in given `displayId`. */
- fun enterSplit(
- displayId: Int,
- leftOrTop: Boolean
- ) {
+ fun enterSplit(displayId: Int, leftOrTop: Boolean) {
getFocusedFreeformTask(displayId)?.let { requestSplit(it, leftOrTop) }
}
private fun getFocusedFreeformTask(displayId: Int): RunningTaskInfo? {
- return shellTaskOrganizer.getRunningTasks(displayId)
- .find { taskInfo -> taskInfo.isFocused &&
- taskInfo.windowingMode == WINDOWING_MODE_FREEFORM }
+ return shellTaskOrganizer.getRunningTasks(displayId).find { taskInfo ->
+ taskInfo.isFocused && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM
+ }
}
/**
@@ -1078,7 +1081,8 @@
leftOrTop: Boolean = false,
) {
val windowingMode = taskInfo.windowingMode
- if (windowingMode == WINDOWING_MODE_FULLSCREEN || windowingMode == WINDOWING_MODE_FREEFORM
+ if (
+ windowingMode == WINDOWING_MODE_FULLSCREEN || windowingMode == WINDOWING_MODE_FREEFORM
) {
val wct = WindowContainerTransaction()
addMoveToSplitChanges(wct, taskInfo)
@@ -1107,9 +1111,9 @@
/**
* Perform checks required on drag move. Create/release fullscreen indicator as needed.
- * Different sources for x and y coordinates are used due to different needs for each:
- * We want split transitions to be based on input coordinates but fullscreen transition
- * to be based on task edge coordinate.
+ * Different sources for x and y coordinates are used due to different needs for each: We want
+ * split transitions to be based on input coordinates but fullscreen transition to be based on
+ * task edge coordinate.
*
* @param taskInfo the task being dragged.
* @param taskSurface SurfaceControl of dragged task.
@@ -1133,9 +1137,16 @@
taskTop: Float
): DesktopModeVisualIndicator.IndicatorType {
// If the visual indicator does not exist, create it.
- val indicator = visualIndicator ?: DesktopModeVisualIndicator(
- syncQueue, taskInfo, displayController, context, taskSurface,
- rootTaskDisplayAreaOrganizer)
+ val indicator =
+ visualIndicator
+ ?: DesktopModeVisualIndicator(
+ syncQueue,
+ taskInfo,
+ displayController,
+ context,
+ taskSurface,
+ rootTaskDisplayAreaOrganizer
+ )
if (visualIndicator == null) visualIndicator = indicator
return indicator.updateIndicatorType(PointF(inputX, taskTop), taskInfo.windowingMode)
}
@@ -1161,10 +1172,11 @@
}
val indicator = visualIndicator ?: return
- val indicatorType = indicator.updateIndicatorType(
- PointF(inputCoordinate.x, taskBounds.top.toFloat()),
- taskInfo.windowingMode
- )
+ val indicatorType =
+ indicator.updateIndicatorType(
+ PointF(inputCoordinate.x, taskBounds.top.toFloat()),
+ taskInfo.windowingMode
+ )
when (indicatorType) {
DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR -> {
moveToFullscreenWithAnimation(taskInfo, position)
@@ -1180,8 +1192,12 @@
DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR -> {
// If task bounds are outside valid drag area, snap them inward and perform a
// transaction to set bounds.
- if (DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(
- taskBounds, validDragArea)) {
+ if (
+ DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(
+ taskBounds,
+ validDragArea
+ )
+ ) {
val wct = WindowContainerTransaction()
wct.setBounds(taskInfo.token, taskBounds)
transitions.startTransition(TRANSIT_CHANGE, wct, null)
@@ -1189,8 +1205,9 @@
releaseVisualIndicator()
}
DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR -> {
- throw IllegalArgumentException("Should not be receiving TO_DESKTOP_INDICATOR for " +
- "a freeform task.")
+ throw IllegalArgumentException(
+ "Should not be receiving TO_DESKTOP_INDICATOR for " + "a freeform task."
+ )
}
}
// A freeform drag-move ended, remove the indicator immediately.
@@ -1205,8 +1222,7 @@
*/
fun onDragPositioningEndThroughStatusBar(inputCoordinates: PointF, taskInfo: RunningTaskInfo) {
val indicator = getVisualIndicator() ?: return
- val indicatorType = indicator
- .updateIndicatorType(inputCoordinates, taskInfo.windowingMode)
+ val indicatorType = indicator.updateIndicatorType(inputCoordinates, taskInfo.windowingMode)
when (indicatorType) {
DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR -> {
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
@@ -1229,16 +1245,12 @@
}
}
- /**
- * Update the exclusion region for a specified task
- */
+ /** Update the exclusion region for a specified task */
fun onExclusionRegionChanged(taskId: Int, exclusionRegion: Region) {
desktopModeTaskRepository.updateTaskExclusionRegions(taskId, exclusionRegion)
}
- /**
- * Remove a previously tracked exclusion region for a specified task.
- */
+ /** Remove a previously tracked exclusion region for a specified task. */
fun removeExclusionRegionForTask(taskId: Int) {
desktopModeTaskRepository.removeExclusionRegion(taskId)
}
@@ -1259,10 +1271,7 @@
* @param listener the listener to add.
* @param callbackExecutor the executor to call the listener on.
*/
- fun setTaskRegionListener(
- listener: Consumer<Region>,
- callbackExecutor: Executor
- ) {
+ fun setTaskRegionListener(listener: Consumer<Region>, callbackExecutor: Executor) {
desktopModeTaskRepository.setExclusionRegionListener(listener, callbackExecutor)
}
@@ -1287,15 +1296,16 @@
}
// Start a new transition to launch the app
- val opts = ActivityOptions.makeBasic().apply {
- launchWindowingMode = WINDOWING_MODE_FREEFORM
- pendingIntentLaunchFlags =
- Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
- setPendingIntentBackgroundActivityStartMode(
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
- )
- isPendingIntentBackgroundActivityLaunchAllowedByPermission = true
- }
+ val opts =
+ ActivityOptions.makeBasic().apply {
+ launchWindowingMode = WINDOWING_MODE_FREEFORM
+ pendingIntentLaunchFlags =
+ Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+ setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
+ )
+ isPendingIntentBackgroundActivityLaunchAllowedByPermission = true
+ }
val wct = WindowContainerTransaction()
wct.sendPendingIntent(launchIntent, null, opts.toBundle())
transitions.startTransition(TRANSIT_OPEN, wct, null /* handler */)
@@ -1321,8 +1331,8 @@
@ExternalThread
private inner class DesktopModeImpl : DesktopMode {
override fun addVisibleTasksListener(
- listener: VisibleTasksListener,
- callbackExecutor: Executor
+ listener: VisibleTasksListener,
+ callbackExecutor: Executor
) {
mainExecutor.execute {
this@DesktopTasksController.addVisibleTasksListener(listener, callbackExecutor)
@@ -1330,8 +1340,8 @@
}
override fun addDesktopGestureExclusionRegionListener(
- listener: Consumer<Region>,
- callbackExecutor: Executor
+ listener: Consumer<Region>,
+ callbackExecutor: Executor
) {
mainExecutor.execute {
this@DesktopTasksController.setTaskRegionListener(listener, callbackExecutor)
@@ -1339,21 +1349,15 @@
}
override fun moveFocusedTaskToDesktop(displayId: Int) {
- mainExecutor.execute {
- this@DesktopTasksController.moveFocusedTaskToDesktop(displayId)
- }
+ mainExecutor.execute { this@DesktopTasksController.moveFocusedTaskToDesktop(displayId) }
}
override fun moveFocusedTaskToFullscreen(displayId: Int) {
- mainExecutor.execute {
- this@DesktopTasksController.enterFullscreen(displayId)
- }
+ mainExecutor.execute { this@DesktopTasksController.enterFullscreen(displayId) }
}
override fun moveFocusedTaskToStageSplit(displayId: Int, leftOrTop: Boolean) {
- mainExecutor.execute {
- this@DesktopTasksController.enterSplit(displayId, leftOrTop)
- }
+ mainExecutor.execute { this@DesktopTasksController.enterSplit(displayId, leftOrTop) }
}
}
@@ -1363,36 +1367,35 @@
IDesktopMode.Stub(), ExternalInterfaceBinder {
private lateinit var remoteListener:
- SingleInstanceRemoteListener<DesktopTasksController, IDesktopTaskListener>
+ SingleInstanceRemoteListener<DesktopTasksController, IDesktopTaskListener>
- private val listener: VisibleTasksListener = object : VisibleTasksListener {
- override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
- KtProtoLog.v(
+ private val listener: VisibleTasksListener =
+ object : VisibleTasksListener {
+ override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
+ KtProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"IDesktopModeImpl: onVisibilityChanged display=%d visible=%d",
displayId,
visibleTasksCount
- )
- remoteListener.call {
- l -> l.onTasksVisibilityChanged(displayId, visibleTasksCount)
+ )
+ remoteListener.call { l ->
+ l.onTasksVisibilityChanged(displayId, visibleTasksCount)
+ }
}
}
- }
init {
remoteListener =
- SingleInstanceRemoteListener<DesktopTasksController, IDesktopTaskListener>(
- controller,
- { c ->
- c.desktopModeTaskRepository.addVisibleTasksListener(
- listener,
- c.mainExecutor
- )
- },
- { c ->
- c.desktopModeTaskRepository.removeVisibleTasksListener(listener)
- }
- )
+ SingleInstanceRemoteListener<DesktopTasksController, IDesktopTaskListener>(
+ controller,
+ { c ->
+ c.desktopModeTaskRepository.addVisibleTasksListener(
+ listener,
+ c.mainExecutor
+ )
+ },
+ { c -> c.desktopModeTaskRepository.removeVisibleTasksListener(listener) }
+ )
}
/** Invalidates this instance, preventing future calls from updating the controller. */
@@ -1402,24 +1405,19 @@
}
override fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition?) {
- ExecutorUtils.executeRemoteCallWithTaskPermission(
- controller,
- "showDesktopApps"
- ) { c -> c.showDesktopApps(displayId, remoteTransition) }
+ ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "showDesktopApps") { c ->
+ c.showDesktopApps(displayId, remoteTransition)
+ }
}
override fun showDesktopApp(taskId: Int) {
- ExecutorUtils.executeRemoteCallWithTaskPermission(
- controller,
- "showDesktopApp"
- ) { c -> c.moveTaskToFront(taskId) }
+ ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "showDesktopApp") { c ->
+ c.moveTaskToFront(taskId)
+ }
}
override fun stashDesktopApps(displayId: Int) {
- KtProtoLog.w(
- WM_SHELL_DESKTOP_MODE,
- "IDesktopModeImpl: stashDesktopApps is deprecated"
- )
+ KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: stashDesktopApps is deprecated")
}
override fun hideStashedDesktopApps(displayId: Int) {
@@ -1444,35 +1442,38 @@
ExecutorUtils.executeRemoteCallWithTaskPermission(
controller,
"onDesktopSplitSelectAnimComplete"
- ) { c -> c.onDesktopSplitSelectAnimComplete(taskInfo) }
+ ) { c ->
+ c.onDesktopSplitSelectAnimComplete(taskInfo)
+ }
}
override fun setTaskListener(listener: IDesktopTaskListener?) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "IDesktopModeImpl: set task listener=%s",
- listener ?: "null"
+ WM_SHELL_DESKTOP_MODE,
+ "IDesktopModeImpl: set task listener=%s",
+ listener ?: "null"
)
- ExecutorUtils.executeRemoteCallWithTaskPermission(
- controller,
- "setTaskListener"
- ) { _ -> listener?.let { remoteListener.register(it) } ?: remoteListener.unregister() }
+ ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "setTaskListener") { _ ->
+ listener?.let { remoteListener.register(it) } ?: remoteListener.unregister()
+ }
}
override fun moveToDesktop(taskId: Int) {
- ExecutorUtils.executeRemoteCallWithTaskPermission(
- controller,
- "moveToDesktop"
- ) { c -> c.moveToDesktop(taskId) }
+ ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "moveToDesktop") { c ->
+ c.moveToDesktop(taskId)
+ }
}
}
companion object {
@JvmField
- val DESKTOP_MODE_INITIAL_BOUNDS_SCALE = SystemProperties
- .getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
+ val DESKTOP_MODE_INITIAL_BOUNDS_SCALE =
+ SystemProperties.getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
}
/** The positions on a screen that a task can snap to. */
- enum class SnapPosition { RIGHT, LEFT }
+ enum class SnapPosition {
+ RIGHT,
+ LEFT
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index e5e435d..98c79d7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -50,26 +50,25 @@
* gesture.
*/
class DragToDesktopTransitionHandler(
- private val context: Context,
- private val transitions: Transitions,
- private val taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
- private val transactionSupplier: Supplier<SurfaceControl.Transaction>
+ private val context: Context,
+ private val transitions: Transitions,
+ private val taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
+ private val transactionSupplier: Supplier<SurfaceControl.Transaction>
) : TransitionHandler {
constructor(
- context: Context,
- transitions: Transitions,
- rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
+ context: Context,
+ transitions: Transitions,
+ rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
) : this(
- context,
- transitions,
- rootTaskDisplayAreaOrganizer,
- Supplier { SurfaceControl.Transaction() }
+ context,
+ transitions,
+ rootTaskDisplayAreaOrganizer,
+ Supplier { SurfaceControl.Transaction() }
)
private val rectEvaluator = RectEvaluator(Rect())
- private val launchHomeIntent = Intent(Intent.ACTION_MAIN)
- .addCategory(Intent.CATEGORY_HOME)
+ private val launchHomeIntent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
private var dragToDesktopStateListener: DragToDesktopStateListener? = null
private lateinit var splitScreenController: SplitScreenController
@@ -107,52 +106,55 @@
* after one of the "end" or "cancel" transitions is merged into this transition.
*/
fun startDragToDesktopTransition(
- taskId: Int,
- dragToDesktopAnimator: MoveToDesktopAnimator,
+ taskId: Int,
+ dragToDesktopAnimator: MoveToDesktopAnimator,
) {
if (inProgress) {
KtProtoLog.v(
- ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
- "DragToDesktop: Drag to desktop transition already in progress."
+ ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
+ "DragToDesktop: Drag to desktop transition already in progress."
)
return
}
- val options = ActivityOptions.makeBasic().apply {
- setTransientLaunch()
- setSourceInfo(SourceInfo.TYPE_DESKTOP_ANIMATION, SystemClock.uptimeMillis())
- pendingIntentCreatorBackgroundActivityStartMode =
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
- }
- val pendingIntent = PendingIntent.getActivity(
+ val options =
+ ActivityOptions.makeBasic().apply {
+ setTransientLaunch()
+ setSourceInfo(SourceInfo.TYPE_DESKTOP_ANIMATION, SystemClock.uptimeMillis())
+ pendingIntentCreatorBackgroundActivityStartMode =
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ }
+ val pendingIntent =
+ PendingIntent.getActivity(
context,
0 /* requestCode */,
launchHomeIntent,
FLAG_MUTABLE or FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT or FILL_IN_COMPONENT,
options.toBundle()
- )
+ )
val wct = WindowContainerTransaction()
wct.sendPendingIntent(pendingIntent, launchHomeIntent, Bundle())
- val startTransitionToken = transitions
- .startTransition(TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP, wct, this)
+ val startTransitionToken =
+ transitions.startTransition(TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP, wct, this)
- transitionState = if (isSplitTask(taskId)) {
- val otherTask = getOtherSplitTask(taskId) ?: throw IllegalStateException(
- "Expected split task to have a counterpart."
- )
- TransitionState.FromSplit(
+ transitionState =
+ if (isSplitTask(taskId)) {
+ val otherTask =
+ getOtherSplitTask(taskId)
+ ?: throw IllegalStateException("Expected split task to have a counterpart.")
+ TransitionState.FromSplit(
draggedTaskId = taskId,
dragAnimator = dragToDesktopAnimator,
startTransitionToken = startTransitionToken,
otherSplitTask = otherTask
- )
- } else {
- TransitionState.FromFullscreen(
+ )
+ } else {
+ TransitionState.FromFullscreen(
draggedTaskId = taskId,
dragAnimator = dragToDesktopAnimator,
startTransitionToken = startTransitionToken
- )
- }
+ )
+ }
}
/**
@@ -216,15 +218,16 @@
}
override fun startAnimation(
- transition: IBinder,
- info: TransitionInfo,
- startTransaction: SurfaceControl.Transaction,
- finishTransaction: SurfaceControl.Transaction,
- finishCallback: Transitions.TransitionFinishCallback
+ transition: IBinder,
+ info: TransitionInfo,
+ startTransaction: SurfaceControl.Transaction,
+ finishTransaction: SurfaceControl.Transaction,
+ finishCallback: Transitions.TransitionFinishCallback
): Boolean {
val state = requireTransitionState()
- val isStartDragToDesktop = info.type == TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP &&
+ val isStartDragToDesktop =
+ info.type == TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP &&
transition == state.startTransitionToken
if (!isStartDragToDesktop) {
return false
@@ -257,13 +260,16 @@
when (state) {
is TransitionState.FromSplit -> {
state.splitRootChange = change
- val layer = if (!state.cancelled) {
- // Normal case, split root goes to the bottom behind everything else.
- appLayers - i
- } else {
- // Cancel-early case, pretend nothing happened so split root stays top.
- dragLayer
- }
+ val layer =
+ if (!state.cancelled) {
+ // Normal case, split root goes to the bottom behind everything
+ // else.
+ appLayers - i
+ } else {
+ // Cancel-early case, pretend nothing happened so split root stays
+ // top.
+ dragLayer
+ }
startTransaction.apply {
setLayer(change.leash, layer)
show(change.leash)
@@ -308,7 +314,10 @@
if (change.taskInfo?.taskId == state.draggedTaskId && !state.cancelled) {
state.draggedTaskChange = change
taskDisplayAreaOrganizer.reparentToDisplayArea(
- change.endDisplayId, change.leash, startTransaction)
+ change.endDisplayId,
+ change.leash,
+ startTransaction
+ )
val bounds = change.endAbsBounds
startTransaction.apply {
setLayer(change.leash, dragLayer)
@@ -339,28 +348,34 @@
}
override fun mergeAnimation(
- transition: IBinder,
- info: TransitionInfo,
- t: SurfaceControl.Transaction,
- mergeTarget: IBinder,
- finishCallback: Transitions.TransitionFinishCallback
+ transition: IBinder,
+ info: TransitionInfo,
+ t: SurfaceControl.Transaction,
+ mergeTarget: IBinder,
+ finishCallback: Transitions.TransitionFinishCallback
) {
val state = requireTransitionState()
- val isCancelTransition = info.type == TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP &&
+ val isCancelTransition =
+ info.type == TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP &&
transition == state.cancelTransitionToken &&
mergeTarget == state.startTransitionToken
- val isEndTransition = info.type == TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP &&
+ val isEndTransition =
+ info.type == TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP &&
mergeTarget == state.startTransitionToken
- val startTransactionFinishT = state.startTransitionFinishTransaction
+ val startTransactionFinishT =
+ state.startTransitionFinishTransaction
?: error("Start transition expected to be waiting for merge but wasn't")
- val startTransitionFinishCb = state.startTransitionFinishCb
+ val startTransitionFinishCb =
+ state.startTransitionFinishCb
?: error("Start transition expected to be waiting for merge but wasn't")
if (isEndTransition) {
info.changes.withIndex().forEach { (i, change) ->
// If we're exiting split, hide the remaining split task.
- if (state is TransitionState.FromSplit &&
- change.taskInfo?.taskId == state.otherSplitTask) {
+ if (
+ state is TransitionState.FromSplit &&
+ change.taskInfo?.taskId == state.otherSplitTask
+ ) {
t.hide(change.leash)
startTransactionFinishT.hide(change.leash)
}
@@ -373,14 +388,16 @@
state.draggedTaskChange = change
} else if (change.taskInfo?.windowingMode == WINDOWING_MODE_FREEFORM) {
// Other freeform tasks that are being restored go behind the dragged task.
- val draggedTaskLeash = state.draggedTaskChange?.leash
+ val draggedTaskLeash =
+ state.draggedTaskChange?.leash
?: error("Expected dragged leash to be non-null")
t.setRelativeLayer(change.leash, draggedTaskLeash, -i)
startTransactionFinishT.setRelativeLayer(change.leash, draggedTaskLeash, -i)
}
}
- val draggedTaskChange = state.draggedTaskChange
+ val draggedTaskChange =
+ state.draggedTaskChange
?: throw IllegalStateException("Expected non-null change of dragged task")
val draggedTaskLeash = draggedTaskChange.leash
val startBounds = draggedTaskChange.startAbsBounds
@@ -395,57 +412,59 @@
val startPosition = state.dragAnimator.position
val unscaledStartWidth = startBounds.width()
val unscaledStartHeight = startBounds.height()
- val unscaledStartBounds = Rect(
- startPosition.x.toInt(),
- startPosition.y.toInt(),
- startPosition.x.toInt() + unscaledStartWidth,
- startPosition.y.toInt() + unscaledStartHeight
- )
+ val unscaledStartBounds =
+ Rect(
+ startPosition.x.toInt(),
+ startPosition.y.toInt(),
+ startPosition.x.toInt() + unscaledStartWidth,
+ startPosition.y.toInt() + unscaledStartHeight
+ )
dragToDesktopStateListener?.onCommitToDesktopAnimationStart(t)
// Accept the merge by applying the merging transaction (applied by #showResizeVeil)
// and finish callback. Show the veil and position the task at the first frame before
// starting the final animation.
- onTaskResizeAnimationListener.onAnimationStart(state.draggedTaskId, t,
- unscaledStartBounds)
+ onTaskResizeAnimationListener.onAnimationStart(
+ state.draggedTaskId,
+ t,
+ unscaledStartBounds
+ )
finishCallback.onTransitionFinished(null /* wct */)
val tx: SurfaceControl.Transaction = transactionSupplier.get()
ValueAnimator.ofObject(rectEvaluator, unscaledStartBounds, endBounds)
- .setDuration(DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS)
- .apply {
- addUpdateListener { animator ->
- val animBounds = animator.animatedValue as Rect
- val animFraction = animator.animatedFraction
- // Progress scale from starting value to 1 as animation plays.
- val animScale = startScale + animFraction * (1 - startScale)
- tx.apply {
- setScale(draggedTaskLeash, animScale, animScale)
- setPosition(
- draggedTaskLeash,
- animBounds.left.toFloat(),
- animBounds.top.toFloat()
- )
- setWindowCrop(
- draggedTaskLeash,
- animBounds.width(),
- animBounds.height()
- )
- }
- onTaskResizeAnimationListener.onBoundsChange(
- state.draggedTaskId,
- tx,
- animBounds
+ .setDuration(DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS)
+ .apply {
+ addUpdateListener { animator ->
+ val animBounds = animator.animatedValue as Rect
+ val animFraction = animator.animatedFraction
+ // Progress scale from starting value to 1 as animation plays.
+ val animScale = startScale + animFraction * (1 - startScale)
+ tx.apply {
+ setScale(draggedTaskLeash, animScale, animScale)
+ setPosition(
+ draggedTaskLeash,
+ animBounds.left.toFloat(),
+ animBounds.top.toFloat()
)
+ setWindowCrop(draggedTaskLeash, animBounds.width(), animBounds.height())
}
- addListener(object : AnimatorListenerAdapter() {
+ onTaskResizeAnimationListener.onBoundsChange(
+ state.draggedTaskId,
+ tx,
+ animBounds
+ )
+ }
+ addListener(
+ object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
onTaskResizeAnimationListener.onAnimationEnd(state.draggedTaskId)
startTransitionFinishCb.onTransitionFinished(null /* null */)
clearState()
}
- })
- start()
- }
+ }
+ )
+ start()
+ }
} else if (isCancelTransition) {
info.changes.forEach { change ->
t.show(change.leash)
@@ -459,8 +478,8 @@
}
override fun handleRequest(
- transition: IBinder,
- request: TransitionRequestInfo
+ transition: IBinder,
+ request: TransitionRequestInfo
): WindowContainerTransaction? {
// Only handle transitions started from shell.
return null
@@ -489,8 +508,8 @@
val state = requireTransitionState()
val dragToDesktopAnimator = state.dragAnimator
- val draggedTaskChange = state.draggedTaskChange
- ?: throw IllegalStateException("Expected non-null task change")
+ val draggedTaskChange =
+ state.draggedTaskChange ?: throw IllegalStateException("Expected non-null task change")
val sc = draggedTaskChange.leash
// Pause the animation that shrinks the window when task is first dragged from fullscreen
dragToDesktopAnimator.cancelAnimator()
@@ -503,29 +522,31 @@
val dy = targetY - y
val tx: SurfaceControl.Transaction = transactionSupplier.get()
ValueAnimator.ofFloat(DRAG_FREEFORM_SCALE, 1f)
- .setDuration(DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS)
- .apply {
- addUpdateListener { animator ->
- val scale = animator.animatedValue as Float
- val fraction = animator.animatedFraction
- val animX = x + (dx * fraction)
- val animY = y + (dy * fraction)
- tx.apply {
- setPosition(sc, animX, animY)
- setScale(sc, scale, scale)
- show(sc)
- apply()
- }
+ .setDuration(DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS)
+ .apply {
+ addUpdateListener { animator ->
+ val scale = animator.animatedValue as Float
+ val fraction = animator.animatedFraction
+ val animX = x + (dx * fraction)
+ val animY = y + (dy * fraction)
+ tx.apply {
+ setPosition(sc, animX, animY)
+ setScale(sc, scale, scale)
+ show(sc)
+ apply()
}
- addListener(object : AnimatorListenerAdapter() {
+ }
+ addListener(
+ object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
dragToDesktopStateListener?.onCancelToDesktopAnimationEnd(tx)
// Start the cancel transition to restore order.
startCancelDragToDesktopTransition()
}
- })
- start()
- }
+ }
+ )
+ start()
+ }
}
private fun startCancelDragToDesktopTransition() {
@@ -536,19 +557,23 @@
// There may have been tasks sent behind home that are not the dragged task (like
// when the dragged task is translucent and that makes the task behind it visible).
// Restore the order of those first.
- state.otherRootChanges.mapNotNull { it.container }.forEach { wc ->
- // TODO(b/322852244): investigate why even though these "other" tasks are
- // reordered in front of home and behind the translucent dragged task, its
- // surface is not visible on screen.
- wct.reorder(wc, true /* toTop */)
- }
- val wc = state.draggedTaskChange?.container
+ state.otherRootChanges
+ .mapNotNull { it.container }
+ .forEach { wc ->
+ // TODO(b/322852244): investigate why even though these "other" tasks are
+ // reordered in front of home and behind the translucent dragged task, its
+ // surface is not visible on screen.
+ wct.reorder(wc, true /* toTop */)
+ }
+ val wc =
+ state.draggedTaskChange?.container
?: error("Dragged task should be non-null before cancelling")
// Then the dragged task a the very top.
wct.reorder(wc, true /* toTop */)
}
is TransitionState.FromSplit -> {
- val wc = state.splitRootChange?.container
+ val wc =
+ state.splitRootChange?.container
?: error("Split root should be non-null before cancelling")
wct.reorder(wc, true /* toTop */)
}
@@ -556,8 +581,8 @@
val homeWc = state.homeToken ?: error("Home task should be non-null before cancelling")
wct.restoreTransientOrder(homeWc)
- state.cancelTransitionToken = transitions.startTransition(
- TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP, wct, this)
+ state.cancelTransitionToken =
+ transitions.startTransition(TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP, wct, this)
}
private fun clearState() {
@@ -571,11 +596,12 @@
private fun getOtherSplitTask(taskId: Int): Int? {
val splitPos = splitScreenController.getSplitPosition(taskId)
if (splitPos == SPLIT_POSITION_UNDEFINED) return null
- val otherTaskPos = if (splitPos == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
- SPLIT_POSITION_TOP_OR_LEFT
- } else {
- SPLIT_POSITION_BOTTOM_OR_RIGHT
- }
+ val otherTaskPos =
+ if (splitPos == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+ SPLIT_POSITION_TOP_OR_LEFT
+ } else {
+ SPLIT_POSITION_BOTTOM_OR_RIGHT
+ }
return splitScreenController.getTaskInfo(otherTaskPos)?.taskId
}
@@ -585,6 +611,7 @@
interface DragToDesktopStateListener {
fun onCommitToDesktopAnimationStart(tx: SurfaceControl.Transaction)
+
fun onCancelToDesktopAnimationEnd(tx: SurfaceControl.Transaction)
}
@@ -601,31 +628,32 @@
abstract var startAborted: Boolean
data class FromFullscreen(
- override val draggedTaskId: Int,
- override val dragAnimator: MoveToDesktopAnimator,
- override val startTransitionToken: IBinder,
- override var startTransitionFinishCb: Transitions.TransitionFinishCallback? = null,
- override var startTransitionFinishTransaction: SurfaceControl.Transaction? = null,
- override var cancelTransitionToken: IBinder? = null,
- override var homeToken: WindowContainerToken? = null,
- override var draggedTaskChange: Change? = null,
- override var cancelled: Boolean = false,
- override var startAborted: Boolean = false,
- var otherRootChanges: MutableList<Change> = mutableListOf()
+ override val draggedTaskId: Int,
+ override val dragAnimator: MoveToDesktopAnimator,
+ override val startTransitionToken: IBinder,
+ override var startTransitionFinishCb: Transitions.TransitionFinishCallback? = null,
+ override var startTransitionFinishTransaction: SurfaceControl.Transaction? = null,
+ override var cancelTransitionToken: IBinder? = null,
+ override var homeToken: WindowContainerToken? = null,
+ override var draggedTaskChange: Change? = null,
+ override var cancelled: Boolean = false,
+ override var startAborted: Boolean = false,
+ var otherRootChanges: MutableList<Change> = mutableListOf()
) : TransitionState()
+
data class FromSplit(
- override val draggedTaskId: Int,
- override val dragAnimator: MoveToDesktopAnimator,
- override val startTransitionToken: IBinder,
- override var startTransitionFinishCb: Transitions.TransitionFinishCallback? = null,
- override var startTransitionFinishTransaction: SurfaceControl.Transaction? = null,
- override var cancelTransitionToken: IBinder? = null,
- override var homeToken: WindowContainerToken? = null,
- override var draggedTaskChange: Change? = null,
- override var cancelled: Boolean = false,
- override var startAborted: Boolean = false,
- var splitRootChange: Change? = null,
- var otherSplitTask: Int
+ override val draggedTaskId: Int,
+ override val dragAnimator: MoveToDesktopAnimator,
+ override val startTransitionToken: IBinder,
+ override var startTransitionFinishCb: Transitions.TransitionFinishCallback? = null,
+ override var startTransitionFinishTransaction: SurfaceControl.Transaction? = null,
+ override var cancelTransitionToken: IBinder? = null,
+ override var homeToken: WindowContainerToken? = null,
+ override var draggedTaskChange: Change? = null,
+ override var cancelled: Boolean = false,
+ override var startAborted: Boolean = false,
+ var splitRootChange: Change? = null,
+ var otherSplitTask: Int
) : TransitionState()
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
index 74b8f83..526cf4d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
@@ -59,6 +59,7 @@
private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
private OnTaskResizeAnimationListener mOnTaskResizeAnimationListener;
+
public EnterDesktopTaskTransitionHandler(
Transitions transitions) {
this(transitions, SurfaceControl.Transaction::new);
@@ -72,11 +73,12 @@
}
void setOnTaskResizeAnimationListener(OnTaskResizeAnimationListener listener) {
- mOnTaskResizeAnimationListener = listener;
+ mOnTaskResizeAnimationListener = listener;
}
/**
* Starts Transition of type TRANSIT_MOVE_TO_DESKTOP
+ *
* @param wct WindowContainerTransaction for transition
* @return the token representing the started transition
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 7342bd1..9f9e256 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -56,7 +56,7 @@
private final Transitions mTransitions;
private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
- private Supplier<SurfaceControl.Transaction> mTransactionSupplier;
+ private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
private Point mPosition;
public ExitDesktopTaskTransitionHandler(
@@ -76,9 +76,10 @@
/**
* Starts Transition of a given type
- * @param type Transition type
- * @param wct WindowContainerTransaction for transition
- * @param position Position of the task when transition is started
+ *
+ * @param type Transition type
+ * @param wct WindowContainerTransaction for transition
+ * @param position Position of the task when transition is started
* @param onAnimationEndCallback to be called after animation
*/
public void startTransition(@WindowManager.TransitionType int type,
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 c469e65..88d0554 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
@@ -86,9 +86,9 @@
.setWindowCrop(leash, startBounds.width(), startBounds.height())
.show(leash)
onTaskResizeAnimationListener.onAnimationStart(
- taskId,
- startTransaction,
- startBounds
+ taskId,
+ startTransaction,
+ startBounds
)
},
onEnd = {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index 11aa402..a126cbe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -30,6 +30,7 @@
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.graphics.Rect;
+import android.gui.TrustedOverlay;
import android.os.Binder;
import android.util.CloseGuard;
import android.util.Slog;
@@ -448,6 +449,14 @@
mSurfaceCreated = true;
mIsInitialized = true;
mSurfaceControl = surfaceControl;
+ // SurfaceControl is expected to be null only in the case of unit tests. Guard against it
+ // to avoid runtime exception in SurfaceControl.Transaction.
+ if (surfaceControl != null) {
+ // TaskView is meant to contain app activities which shouldn't have trusted overlays
+ // flag set even when itself reparented in a window which is trusted.
+ mTransaction.setTrustedOverlay(surfaceControl, TrustedOverlay.DISABLED)
+ .apply();
+ }
notifyInitialized();
mShellExecutor.execute(() -> {
if (mTaskToken == null) {
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 9afb057..74b091f 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
@@ -278,11 +278,9 @@
public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {
if (visible && stage != STAGE_TYPE_UNDEFINED) {
DesktopModeWindowDecoration decor = mWindowDecorByTaskId.get(taskId);
- if (decor == null || !DesktopModeStatus.canEnterDesktopMode(mContext)
- || decor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
- return;
+ if (decor != null && DesktopModeStatus.canEnterDesktopMode(mContext)) {
+ mDesktopTasksController.moveToSplit(decor.mTaskInfo);
}
- mDesktopTasksController.moveToSplit(decor.mTaskInfo);
}
}
});
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 63b4538..386a606c 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -8617,6 +8617,7 @@
@SystemApi
@NonNull
@RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+ // TODO also open to MODIFY_AUDIO_SETTINGS_PRIVILEGED b/341780042
public static List<AudioVolumeGroup> getAudioVolumeGroups() {
final IAudioService service = getService();
try {
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index e612645..c8b9da5 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -142,7 +142,7 @@
@UnsupportedAppUsage
int getStreamMaxVolume(int streamType);
- @EnforcePermission("MODIFY_AUDIO_ROUTING")
+ @EnforcePermission(anyOf={"MODIFY_AUDIO_SETTINGS_PRIVILEGED", "MODIFY_AUDIO_ROUTING"})
List<AudioVolumeGroup> getAudioVolumeGroups();
@EnforcePermission(anyOf={"MODIFY_AUDIO_SETTINGS_PRIVILEGED", "MODIFY_AUDIO_ROUTING"})
diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java
index a2a16ef..9899e4e 100644
--- a/media/java/android/media/RoutingSessionInfo.java
+++ b/media/java/android/media/RoutingSessionInfo.java
@@ -901,6 +901,14 @@
* <p>By default the transfer initiation user handle and package name are set to {@code
* null}.
*/
+ // The UserHandleName warning suggests the name should be "doFooAsUser". But the UserHandle
+ // parameter of this function is stored in a field, and not used to execute an operation on
+ // a specific user.
+ // The MissingGetterMatchingBuilder requires a getTransferInitiator function. But said
+ // getter is not included because the returned package name and user handle is always either
+ // null or the values that correspond to the calling app, and that information is obtainable
+ // via RoutingController#wasTransferInitiatedBySelf.
+ @SuppressWarnings({"UserHandleName", "MissingGetterMatchingBuilder"})
@NonNull
@FlaggedApi(FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES)
public Builder setTransferInitiator(
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroup.java b/media/java/android/media/audiopolicy/AudioVolumeGroup.java
index d607126..0f5fbcc 100644
--- a/media/java/android/media/audiopolicy/AudioVolumeGroup.java
+++ b/media/java/android/media/audiopolicy/AudioVolumeGroup.java
@@ -31,6 +31,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
/**
* A class to create the association between different playback attributes
@@ -118,6 +119,12 @@
&& Arrays.equals(mAudioAttributes, thatAvg.mAudioAttributes);
}
+ @Override
+ public int hashCode() {
+ return Objects.hash(mName, mId,
+ Arrays.hashCode(mAudioAttributes), Arrays.hashCode(mLegacyStreamTypes));
+ }
+
/**
* @return List of {@link AudioAttributes} involved in this {@link AudioVolumeGroup}.
*/
diff --git a/media/java/android/media/projection/IMediaProjection.aidl b/media/java/android/media/projection/IMediaProjection.aidl
index 2fb0af5..7a1cf92 100644
--- a/media/java/android/media/projection/IMediaProjection.aidl
+++ b/media/java/android/media/projection/IMediaProjection.aidl
@@ -39,8 +39,8 @@
void unregisterCallback(IMediaProjectionCallback callback);
/**
- * Returns the {@link LaunchCookie} identifying the task to record, or {@code null} if
- * there is none.
+ * Returns the {@link LaunchCookie} identifying the task to record. Will always be set
+ * regardless of starting a new task or recent task
*/
@EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
@@ -48,8 +48,16 @@
LaunchCookie getLaunchCookie();
/**
- * Updates the {@link LaunchCookie} identifying the task to record, or {@code null} if
- * there is none.
+ * Returns the taskId identifying the task to record. Will only be set in the case of
+ * launching a recent task, otherwise set to -1.
+ */
+ @EnforcePermission("MANAGE_MEDIA_PROJECTION")
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MANAGE_MEDIA_PROJECTION)")
+ int getTaskId();
+
+ /**
+ * Updates the {@link LaunchCookie} identifying the task to record.
*/
@EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
@@ -57,6 +65,15 @@
void setLaunchCookie(in LaunchCookie launchCookie);
/**
+ * Updates the taskId identifying the task to record.
+ */
+ @EnforcePermission("MANAGE_MEDIA_PROJECTION")
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MANAGE_MEDIA_PROJECTION)")
+ void setTaskId(in int taskId);
+
+
+ /**
* Returns {@code true} if this token is still valid. A token is valid as long as the token
* hasn't timed out before it was used, and the token is only used once.
*
diff --git a/media/java/android/media/tv/TvStreamConfig.java b/media/java/android/media/tv/TvStreamConfig.java
index 7ea93b4..1f51c7a 100644
--- a/media/java/android/media/tv/TvStreamConfig.java
+++ b/media/java/android/media/tv/TvStreamConfig.java
@@ -23,6 +23,8 @@
import android.os.Parcelable;
import android.util.Log;
+import java.util.Objects;
+
/**
* @hide
*/
@@ -177,4 +179,9 @@
&& config.mMaxWidth == mMaxWidth
&& config.mMaxHeight == mMaxHeight;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mGeneration, mStreamId, mType, mMaxWidth, mMaxHeight);
+ }
}
diff --git a/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java b/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
index 0df36af..6860c0b 100644
--- a/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
+++ b/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
@@ -28,6 +28,7 @@
* outside the test it is implemented by the system server.
*/
public final class FakeIMediaProjection extends IMediaProjection.Stub {
+ int mTaskId = -1;
boolean mIsStarted = false;
LaunchCookie mLaunchCookie = null;
IMediaProjectionCallback mIMediaProjectionCallback = null;
@@ -87,6 +88,13 @@
@Override
@EnforcePermission(MANAGE_MEDIA_PROJECTION)
+ public int getTaskId() throws RemoteException {
+ getTaskId_enforcePermission();
+ return mTaskId;
+ }
+
+ @Override
+ @EnforcePermission(MANAGE_MEDIA_PROJECTION)
public void setLaunchCookie(LaunchCookie launchCookie) throws RemoteException {
setLaunchCookie_enforcePermission();
mLaunchCookie = launchCookie;
@@ -94,6 +102,13 @@
@Override
@EnforcePermission(MANAGE_MEDIA_PROJECTION)
+ public void setTaskId(int taskId) throws RemoteException {
+ setTaskId_enforcePermission();
+ mTaskId = taskId;
+ }
+
+ @Override
+ @EnforcePermission(MANAGE_MEDIA_PROJECTION)
public boolean isValid() throws RemoteException {
isValid_enforcePermission();
return true;
diff --git a/packages/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml
index 39abbb986..9ddc7ab 100644
--- a/packages/CredentialManager/res/values-hr/strings.xml
+++ b/packages/CredentialManager/res/values-hr/strings.xml
@@ -75,7 +75,7 @@
<string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"Otključajte opcije za prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Odaberite spremljeni pristupni ključ za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Odaberite spremljenu zaporku za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Odaberite spremljene podatke za prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Odaberite podatke za prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> koje želite spremiti"</string>
<string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"Odaberite račun za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Želite li odabrati opciju za <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"Želite li koristiti te podatke u aplikaciji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
diff --git a/packages/CredentialManager/wear/robotests/Android.bp b/packages/CredentialManager/wear/robotests/Android.bp
index c0a1822..589a3d6 100644
--- a/packages/CredentialManager/wear/robotests/Android.bp
+++ b/packages/CredentialManager/wear/robotests/Android.bp
@@ -25,4 +25,5 @@
],
java_resource_dirs: ["config"],
upstream: true,
+ strict_mode: false,
}
diff --git a/packages/InputDevices/res/values-af/strings.xml b/packages/InputDevices/res/values-af/strings.xml
index 9369140..7e2561f 100644
--- a/packages/InputDevices/res/values-af/strings.xml
+++ b/packages/InputDevices/res/values-af/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgies"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thais (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-am/strings.xml b/packages/InputDevices/res/values-am/strings.xml
index 16f6437..3053c44 100644
--- a/packages/InputDevices/res/values-am/strings.xml
+++ b/packages/InputDevices/res/values-am/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ጂዮርጂያኛ"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ታይላንድኛ (ኬድማኒ)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ታይላንድኛ (ፓታሾት)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ar/strings.xml b/packages/InputDevices/res/values-ar/strings.xml
index 93223ba..c5be208 100644
--- a/packages/InputDevices/res/values-ar/strings.xml
+++ b/packages/InputDevices/res/values-ar/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"الجورجية"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"التايلاندية (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"التايلاندية (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-as/strings.xml b/packages/InputDevices/res/values-as/strings.xml
index c57b591..15aa34d 100644
--- a/packages/InputDevices/res/values-as/strings.xml
+++ b/packages/InputDevices/res/values-as/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"থাই (কেডমানি)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"থাই (পাটাচ’টে)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-az/strings.xml b/packages/InputDevices/res/values-az/strings.xml
index 9c6bdb3..765d55b 100644
--- a/packages/InputDevices/res/values-az/strings.xml
+++ b/packages/InputDevices/res/values-az/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gürcü"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tay (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tay (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-b+sr+Latn/strings.xml b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
index 80ecff5..9b52c34 100644
--- a/packages/InputDevices/res/values-b+sr+Latn/strings.xml
+++ b/packages/InputDevices/res/values-b+sr+Latn/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzijska"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"tajski (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajski (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-be/strings.xml b/packages/InputDevices/res/values-be/strings.xml
index c5aa66f..1b6491a 100644
--- a/packages/InputDevices/res/values-be/strings.xml
+++ b/packages/InputDevices/res/values-be/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузінская"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Тайская (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайская (Патачотэ)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-bg/strings.xml b/packages/InputDevices/res/values-bg/strings.xml
index 1260d6a..4d70bf5 100644
--- a/packages/InputDevices/res/values-bg/strings.xml
+++ b/packages/InputDevices/res/values-bg/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузински"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"тайландски (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"тайландски (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-bn/strings.xml b/packages/InputDevices/res/values-bn/strings.xml
index a038da9..7c430d3 100644
--- a/packages/InputDevices/res/values-bn/strings.xml
+++ b/packages/InputDevices/res/values-bn/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"জর্জিয়ান"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"থাই (কেডমানি)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"থাই (পাট্টাচোটে)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-bs/strings.xml b/packages/InputDevices/res/values-bs/strings.xml
index 12e93bc..c47dad3 100644
--- a/packages/InputDevices/res/values-bs/strings.xml
+++ b/packages/InputDevices/res/values-bs/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzijski"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"tajlandski (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajlandski (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ca/strings.xml b/packages/InputDevices/res/values-ca/strings.xml
index 8a1e059..fe5a092 100644
--- a/packages/InputDevices/res/values-ca/strings.xml
+++ b/packages/InputDevices/res/values-ca/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgià"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-cs/strings.xml b/packages/InputDevices/res/values-cs/strings.xml
index 9ee17e1..4e3416c 100644
--- a/packages/InputDevices/res/values-cs/strings.xml
+++ b/packages/InputDevices/res/values-cs/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzínština"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"thajština (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thajština (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-da/strings.xml b/packages/InputDevices/res/values-da/strings.xml
index db75d3e..c263224 100644
--- a/packages/InputDevices/res/values-da/strings.xml
+++ b/packages/InputDevices/res/values-da/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisk"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-de/strings.xml b/packages/InputDevices/res/values-de/strings.xml
index 3db695e..5876891 100644
--- a/packages/InputDevices/res/values-de/strings.xml
+++ b/packages/InputDevices/res/values-de/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisch"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thailändisch (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thailändisch (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-el/strings.xml b/packages/InputDevices/res/values-el/strings.xml
index cb7aa2c..78677b3 100644
--- a/packages/InputDevices/res/values-el/strings.xml
+++ b/packages/InputDevices/res/values-el/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Γεωργιανά"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Ταϊλανδικά (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Ταϊλανδικά (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-en-rAU/strings.xml b/packages/InputDevices/res/values-en-rAU/strings.xml
index d113201..356ebd4 100644
--- a/packages/InputDevices/res/values-en-rAU/strings.xml
+++ b/packages/InputDevices/res/values-en-rAU/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-en-rCA/strings.xml b/packages/InputDevices/res/values-en-rCA/strings.xml
index cae7f00..1d7ba3d 100644
--- a/packages/InputDevices/res/values-en-rCA/strings.xml
+++ b/packages/InputDevices/res/values-en-rCA/strings.xml
@@ -52,4 +52,6 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbian (Latin)"</string>
+ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-en-rGB/strings.xml b/packages/InputDevices/res/values-en-rGB/strings.xml
index d113201..356ebd4 100644
--- a/packages/InputDevices/res/values-en-rGB/strings.xml
+++ b/packages/InputDevices/res/values-en-rGB/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-en-rIN/strings.xml b/packages/InputDevices/res/values-en-rIN/strings.xml
index d113201..356ebd4 100644
--- a/packages/InputDevices/res/values-en-rIN/strings.xml
+++ b/packages/InputDevices/res/values-en-rIN/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-en-rXC/strings.xml b/packages/InputDevices/res/values-en-rXC/strings.xml
index 71c84da..a231d4c 100644
--- a/packages/InputDevices/res/values-en-rXC/strings.xml
+++ b/packages/InputDevices/res/values-en-rXC/strings.xml
@@ -52,4 +52,6 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbian (Latin)"</string>
+ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
</resources>
diff --git a/packages/InputDevices/res/values-es-rUS/strings.xml b/packages/InputDevices/res/values-es-rUS/strings.xml
index 7490f7d..c20d928 100644
--- a/packages/InputDevices/res/values-es-rUS/strings.xml
+++ b/packages/InputDevices/res/values-es-rUS/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tailandés (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandés (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-es/strings.xml b/packages/InputDevices/res/values-es/strings.xml
index 22b8cda..5c40ca82 100644
--- a/packages/InputDevices/res/values-es/strings.xml
+++ b/packages/InputDevices/res/values-es/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tailandés (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandés (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-et/strings.xml b/packages/InputDevices/res/values-et/strings.xml
index 34fd3d7..48eb369 100644
--- a/packages/InputDevices/res/values-et/strings.xml
+++ b/packages/InputDevices/res/values-et/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruusia"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"tai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-eu/strings.xml b/packages/InputDevices/res/values-eu/strings.xml
index 15535fd..57af1f7 100644
--- a/packages/InputDevices/res/values-eu/strings.xml
+++ b/packages/InputDevices/res/values-eu/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiarra"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thailandiarra (kedmanee-a)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thailandiarra (pattachote-a)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-fa/strings.xml b/packages/InputDevices/res/values-fa/strings.xml
index 11280dd..6ab8411 100644
--- a/packages/InputDevices/res/values-fa/strings.xml
+++ b/packages/InputDevices/res/values-fa/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"گرجستانی"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"تایلندی (کدمانی)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"تایلندی (پاتاچوته)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-fi/strings.xml b/packages/InputDevices/res/values-fi/strings.xml
index 6c6d4cf..2c69b29 100644
--- a/packages/InputDevices/res/values-fi/strings.xml
+++ b/packages/InputDevices/res/values-fi/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"georgia"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"thai (kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thai (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-fr-rCA/strings.xml b/packages/InputDevices/res/values-fr-rCA/strings.xml
index 5c931cf..a4656ff 100644
--- a/packages/InputDevices/res/values-fr-rCA/strings.xml
+++ b/packages/InputDevices/res/values-fr-rCA/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Géorgien"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thaï (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thaï (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-fr/strings.xml b/packages/InputDevices/res/values-fr/strings.xml
index 1323675..76c4815 100644
--- a/packages/InputDevices/res/values-fr/strings.xml
+++ b/packages/InputDevices/res/values-fr/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Géorgien"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thaï (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thaï (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-gl/strings.xml b/packages/InputDevices/res/values-gl/strings.xml
index cedff5b..133fbf7 100644
--- a/packages/InputDevices/res/values-gl/strings.xml
+++ b/packages/InputDevices/res/values-gl/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Xeorxiano"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tailandés (kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandés (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-gu/strings.xml b/packages/InputDevices/res/values-gu/strings.xml
index cbd4c40..a3c98ae 100644
--- a/packages/InputDevices/res/values-gu/strings.xml
+++ b/packages/InputDevices/res/values-gu/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"જ્યોર્જિઅન"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"થાઇ (કેડમાની)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"થાઇ (પટ્ટાશોટે)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml
index 7e3df82..fafc42d 100644
--- a/packages/InputDevices/res/values-hi/strings.xml
+++ b/packages/InputDevices/res/values-hi/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"जॉर्जियन कीबोर्ड का लेआउट"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"थाई (केडमेनी)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"थाई (पटैचोटे)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-hr/strings.xml b/packages/InputDevices/res/values-hr/strings.xml
index ba3dc51..d8e7ec4 100644
--- a/packages/InputDevices/res/values-hr/strings.xml
+++ b/packages/InputDevices/res/values-hr/strings.xml
@@ -3,53 +3,57 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="8016145283189546017">"Uređaji za unos"</string>
<string name="keyboard_layouts_label" msgid="6688773268302087545">"Android tipkovnica"</string>
- <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"engleska (UK)"</string>
- <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"engleska (SAD)"</string>
- <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"engleska (SAD), međunarodna"</string>
- <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"engleska (SAD), Colemakov raspored"</string>
- <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"engleska (SAD), Dvorakov raspored"</string>
- <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"Engleska (SAD), raspored Workman"</string>
- <string name="keyboard_layout_german_label" msgid="8451565865467909999">"njemačka"</string>
- <string name="keyboard_layout_french_label" msgid="813450119589383723">"francuska"</string>
+ <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"engleski (UK)"</string>
+ <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"engleski (SAD)"</string>
+ <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"engleski (SAD), međunarodni raspored"</string>
+ <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"engleski (SAD), Colemakov raspored"</string>
+ <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"engleski (SAD), Dvorakov raspored"</string>
+ <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"engleski (SAD), raspored Workman"</string>
+ <string name="keyboard_layout_german_label" msgid="8451565865467909999">"njemački"</string>
+ <string name="keyboard_layout_french_label" msgid="813450119589383723">"francuski"</string>
<string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francuska (Kanada)"</string>
- <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruska"</string>
- <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruska, raspored Maca"</string>
- <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španjolska"</string>
- <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"švicarsko-francuska"</string>
- <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"švicarsko-njemačka"</string>
- <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgijska"</string>
- <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bugarska"</string>
- <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"bugarska (fonetska)"</string>
- <string name="keyboard_layout_italian" msgid="6497079660449781213">"talijanska"</string>
- <string name="keyboard_layout_danish" msgid="8036432066627127851">"danska"</string>
- <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norveška"</string>
- <string name="keyboard_layout_swedish" msgid="732959109088479351">"švedska"</string>
- <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finska"</string>
- <string name="keyboard_layout_croatian" msgid="4172229471079281138">"hrvatska"</string>
- <string name="keyboard_layout_czech" msgid="1349256901452975343">"češka"</string>
- <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Češka QWERTY tipkovnica"</string>
- <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estonska"</string>
- <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"mađarska"</string>
- <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandska"</string>
- <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazilska"</string>
- <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalska"</string>
- <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovačka"</string>
- <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenska"</string>
- <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turska"</string>
+ <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruski"</string>
+ <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruski, raspored na Macu"</string>
+ <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španjolski"</string>
+ <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"francuski (Švicarska)"</string>
+ <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"njemački (Švicarska)"</string>
+ <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgijski raspored"</string>
+ <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bugarski"</string>
+ <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"bugarski (fonetski)"</string>
+ <string name="keyboard_layout_italian" msgid="6497079660449781213">"talijanski"</string>
+ <string name="keyboard_layout_danish" msgid="8036432066627127851">"danski"</string>
+ <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norveški"</string>
+ <string name="keyboard_layout_swedish" msgid="732959109088479351">"švedski"</string>
+ <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finski"</string>
+ <string name="keyboard_layout_croatian" msgid="4172229471079281138">"hrvatski"</string>
+ <string name="keyboard_layout_czech" msgid="1349256901452975343">"češki"</string>
+ <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"češki (QWERTY tipkovnica)"</string>
+ <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estonski"</string>
+ <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"mađarski"</string>
+ <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandski"</string>
+ <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"portugalski (Brazil)"</string>
+ <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalski"</string>
+ <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovački"</string>
+ <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenski"</string>
+ <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turski"</string>
<string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"turski F"</string>
- <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinska"</string>
+ <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinski"</string>
<string name="keyboard_layout_arabic" msgid="5671970465174968712">"arapski"</string>
<string name="keyboard_layout_greek" msgid="7289253560162386040">"grčki"</string>
<string name="keyboard_layout_hebrew" msgid="7241473985890173812">"hebrejski"</string>
<string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"litavski"</string>
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"španjolski (Latinska Amerika)"</string>
- <string name="keyboard_layout_latvian" msgid="4405417142306250595">"latvijska"</string>
+ <string name="keyboard_layout_latvian" msgid="4405417142306250595">"latvijski"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"perzijski"</string>
<string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"azerbajdžanski"</string>
<string name="keyboard_layout_polish" msgid="1121588624094925325">"poljski"</string>
<string name="keyboard_layout_belarusian" msgid="7619281752698687588">"bjeloruski"</string>
- <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Mongolski"</string>
- <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzijska"</string>
- <string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"tajlandski (kedmanee)"</string>
- <string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tajski (pattachote)"</string>
+ <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"mongolski"</string>
+ <string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzijski"</string>
+ <string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"tajski (kedmanee)"</string>
+ <string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajski (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-hu/strings.xml b/packages/InputDevices/res/values-hu/strings.xml
index c42e009..88c532e 100644
--- a/packages/InputDevices/res/values-hu/strings.xml
+++ b/packages/InputDevices/res/values-hu/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"grúz"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"thai (kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thai (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml
index d85cf9d..ef4128e 100644
--- a/packages/InputDevices/res/values-hy/strings.xml
+++ b/packages/InputDevices/res/values-hy/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"վրացերեն"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"թայերեն (քեդմանի)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"թայերեն (պատաչոտ)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-in/strings.xml b/packages/InputDevices/res/values-in/strings.xml
index d504540..5ed73dd 100644
--- a/packages/InputDevices/res/values-in/strings.xml
+++ b/packages/InputDevices/res/values-in/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgia"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-is/strings.xml b/packages/InputDevices/res/values-is/strings.xml
index 637874c..12bdf3d 100644
--- a/packages/InputDevices/res/values-is/strings.xml
+++ b/packages/InputDevices/res/values-is/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"georgíska"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Taílenskt (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Taílenskt (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-it/strings.xml b/packages/InputDevices/res/values-it/strings.xml
index eed8316..97a2359 100644
--- a/packages/InputDevices/res/values-it/strings.xml
+++ b/packages/InputDevices/res/values-it/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-iw/strings.xml b/packages/InputDevices/res/values-iw/strings.xml
index 8cfe2cb..0f7a341 100644
--- a/packages/InputDevices/res/values-iw/strings.xml
+++ b/packages/InputDevices/res/values-iw/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"גיאורגית"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"תאית (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"תאית (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ja/strings.xml b/packages/InputDevices/res/values-ja/strings.xml
index d1b334b..f6cfd43 100644
--- a/packages/InputDevices/res/values-ja/strings.xml
+++ b/packages/InputDevices/res/values-ja/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ジョージア語"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"タイ語(Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"タイ語(Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ka/strings.xml b/packages/InputDevices/res/values-ka/strings.xml
index 8928f68..4eebe6b 100644
--- a/packages/InputDevices/res/values-ka/strings.xml
+++ b/packages/InputDevices/res/values-ka/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ქართული"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ტაილანდური (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ტაილანდური (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-kk/strings.xml b/packages/InputDevices/res/values-kk/strings.xml
index cf3d3ca..b1ca40a 100644
--- a/packages/InputDevices/res/values-kk/strings.xml
+++ b/packages/InputDevices/res/values-kk/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузин"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Тай (кедмани)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тай (паттачот)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-km/strings.xml b/packages/InputDevices/res/values-km/strings.xml
index 53eb6f5..abf5551 100644
--- a/packages/InputDevices/res/values-km/strings.xml
+++ b/packages/InputDevices/res/values-km/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ហ្សកហ្ស៊ី"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ថៃ (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ថៃ (ប៉ាតាឈោត)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-kn/strings.xml b/packages/InputDevices/res/values-kn/strings.xml
index c743a6e..94d65bd 100644
--- a/packages/InputDevices/res/values-kn/strings.xml
+++ b/packages/InputDevices/res/values-kn/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ಜಾರ್ಜಿಯನ್"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ಥಾಯ್ (ಕೆಡ್ಮನೀ)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ಥಾಯ್ (ಪಟ್ಟಚೋಟ್)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ko/strings.xml b/packages/InputDevices/res/values-ko/strings.xml
index 0e375dd..fa2d9da 100644
--- a/packages/InputDevices/res/values-ko/strings.xml
+++ b/packages/InputDevices/res/values-ko/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"조지아어"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"태국어(Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"태국어(Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ky/strings.xml b/packages/InputDevices/res/values-ky/strings.xml
index dad5c91..9434840 100644
--- a/packages/InputDevices/res/values-ky/strings.xml
+++ b/packages/InputDevices/res/values-ky/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузинче"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Тайча (Kedmanee баскычтобу)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайча (Pattachote баскычтобу)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-lo/strings.xml b/packages/InputDevices/res/values-lo/strings.xml
index 0794bde..95a8903 100644
--- a/packages/InputDevices/res/values-lo/strings.xml
+++ b/packages/InputDevices/res/values-lo/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ຈໍຈຽນ"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ໄທ (ເກດມະນີ)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ໄທ (ປັດຕະໂຊຕິ)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-lt/strings.xml b/packages/InputDevices/res/values-lt/strings.xml
index 0cceec7..ac2a689 100644
--- a/packages/InputDevices/res/values-lt/strings.xml
+++ b/packages/InputDevices/res/values-lt/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzinų"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tajų („Kedmanee“)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tajų („Pattachote“)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-lv/strings.xml b/packages/InputDevices/res/values-lv/strings.xml
index 9b52854..3cd4da7 100644
--- a/packages/InputDevices/res/values-lv/strings.xml
+++ b/packages/InputDevices/res/values-lv/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzīnu"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Taju valoda (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Taju (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-mk/strings.xml b/packages/InputDevices/res/values-mk/strings.xml
index 4e8be46..b91fcc1 100644
--- a/packages/InputDevices/res/values-mk/strings.xml
+++ b/packages/InputDevices/res/values-mk/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузиски"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"тајландски (кедмани)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"тајландски (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ml/strings.xml b/packages/InputDevices/res/values-ml/strings.xml
index 4b2a5fd..408ae13 100644
--- a/packages/InputDevices/res/values-ml/strings.xml
+++ b/packages/InputDevices/res/values-ml/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ജോര്ജ്ജിയൻ"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"തായ് (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"തായ് (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-mn/strings.xml b/packages/InputDevices/res/values-mn/strings.xml
index a7a1799..51f1a14 100644
--- a/packages/InputDevices/res/values-mn/strings.xml
+++ b/packages/InputDevices/res/values-mn/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Гүрж"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Тай (кедмани)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тай (паттачоте)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-mr/strings.xml b/packages/InputDevices/res/values-mr/strings.xml
index 5e4baa0..47cebf1 100644
--- a/packages/InputDevices/res/values-mr/strings.xml
+++ b/packages/InputDevices/res/values-mr/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"जॉर्जियन"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"थाई (केडमानी)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"थाई (पट्टाचोटे)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ms/strings.xml b/packages/InputDevices/res/values-ms/strings.xml
index 9e4c190..9a1c4f7 100644
--- a/packages/InputDevices/res/values-ms/strings.xml
+++ b/packages/InputDevices/res/values-ms/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Bahasa Georgia"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-my/strings.xml b/packages/InputDevices/res/values-my/strings.xml
index 5dbdc70..009a6c6 100644
--- a/packages/InputDevices/res/values-my/strings.xml
+++ b/packages/InputDevices/res/values-my/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ဂျော်ဂျီယာ"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ထိုင်း (ကတ်မနီး)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ထိုင်း (ပတ်တာချုတ်)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-nb/strings.xml b/packages/InputDevices/res/values-nb/strings.xml
index 1e9af39..2545448 100644
--- a/packages/InputDevices/res/values-nb/strings.xml
+++ b/packages/InputDevices/res/values-nb/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisk"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ne/strings.xml b/packages/InputDevices/res/values-ne/strings.xml
index ab22576..e85d615 100644
--- a/packages/InputDevices/res/values-ne/strings.xml
+++ b/packages/InputDevices/res/values-ne/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"जर्जियाली"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"थाई (केडमानी)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"थाई (पत्ताचोते)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-nl/strings.xml b/packages/InputDevices/res/values-nl/strings.xml
index d28ee9b..7fe2153 100644
--- a/packages/InputDevices/res/values-nl/strings.xml
+++ b/packages/InputDevices/res/values-nl/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgisch"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-or/strings.xml b/packages/InputDevices/res/values-or/strings.xml
index e92c155..8df615e 100644
--- a/packages/InputDevices/res/values-or/strings.xml
+++ b/packages/InputDevices/res/values-or/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ଜର୍ଜିଆନ୍"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ଥାଇ (କେଡମାନି)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ଥାଇ (ପାଟ୍ଟାଚୋଟେ)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-pa/strings.xml b/packages/InputDevices/res/values-pa/strings.xml
index f766297..b0a140e 100644
--- a/packages/InputDevices/res/values-pa/strings.xml
+++ b/packages/InputDevices/res/values-pa/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ਜਾਰਜੀਆਈ"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ਥਾਈ (ਕੇਦਮਨੀ)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ਥਾਈ (ਪੈਟਾਸ਼ੋਟੇ)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-pl/strings.xml b/packages/InputDevices/res/values-pl/strings.xml
index e202463..c44cab5 100644
--- a/packages/InputDevices/res/values-pl/strings.xml
+++ b/packages/InputDevices/res/values-pl/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruziński"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"tajski (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajski (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-pt-rBR/strings.xml b/packages/InputDevices/res/values-pt-rBR/strings.xml
index 4a0c3be..6fa852b 100644
--- a/packages/InputDevices/res/values-pt-rBR/strings.xml
+++ b/packages/InputDevices/res/values-pt-rBR/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tailandês (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandês (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-pt-rPT/strings.xml b/packages/InputDevices/res/values-pt-rPT/strings.xml
index c54b620..b768467 100644
--- a/packages/InputDevices/res/values-pt-rPT/strings.xml
+++ b/packages/InputDevices/res/values-pt-rPT/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tailandês (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandês (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-pt/strings.xml b/packages/InputDevices/res/values-pt/strings.xml
index 4a0c3be..6fa852b 100644
--- a/packages/InputDevices/res/values-pt/strings.xml
+++ b/packages/InputDevices/res/values-pt/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiano"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tailandês (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tailandês (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ro/strings.xml b/packages/InputDevices/res/values-ro/strings.xml
index d91635b..9dc2841 100644
--- a/packages/InputDevices/res/values-ro/strings.xml
+++ b/packages/InputDevices/res/values-ro/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgiană"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thailandeză (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thailandeză (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml
index da1a83a..9612717b 100644
--- a/packages/InputDevices/res/values-ru/strings.xml
+++ b/packages/InputDevices/res/values-ru/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузинский"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Тайский (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайский (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-si/strings.xml b/packages/InputDevices/res/values-si/strings.xml
index 97aed62..2151f44 100644
--- a/packages/InputDevices/res/values-si/strings.xml
+++ b/packages/InputDevices/res/values-si/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ජෝර්ජියානු"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"තායි (කෙඩ්මනී)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"තායි (පට්ටචෝටේ)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sk/strings.xml b/packages/InputDevices/res/values-sk/strings.xml
index 6f387ad..c8b6021 100644
--- a/packages/InputDevices/res/values-sk/strings.xml
+++ b/packages/InputDevices/res/values-sk/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzínske"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"thajčina (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thajčina (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sl/strings.xml b/packages/InputDevices/res/values-sl/strings.xml
index 32ca0ad..1e04ae1 100644
--- a/packages/InputDevices/res/values-sl/strings.xml
+++ b/packages/InputDevices/res/values-sl/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"gruzinščina"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"tajščina (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"tajščina (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sq/strings.xml b/packages/InputDevices/res/values-sq/strings.xml
index c33ba4a..8ad13f4 100644
--- a/packages/InputDevices/res/values-sq/strings.xml
+++ b/packages/InputDevices/res/values-sq/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gjeorgjisht"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tajlandisht (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tajlandisht (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sr/strings.xml b/packages/InputDevices/res/values-sr/strings.xml
index 0b434d7..28cd5ca 100644
--- a/packages/InputDevices/res/values-sr/strings.xml
+++ b/packages/InputDevices/res/values-sr/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"грузијска"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"тајски (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"тајски (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sv/strings.xml b/packages/InputDevices/res/values-sv/strings.xml
index 3d08415..c24c300 100644
--- a/packages/InputDevices/res/values-sv/strings.xml
+++ b/packages/InputDevices/res/values-sv/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"georgiska"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"thailändska (pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-sw/strings.xml b/packages/InputDevices/res/values-sw/strings.xml
index 42714a5..0cf002e 100644
--- a/packages/InputDevices/res/values-sw/strings.xml
+++ b/packages/InputDevices/res/values-sw/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Kijojia"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Kithai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Kitai (Kipatachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ta/strings.xml b/packages/InputDevices/res/values-ta/strings.xml
index f8bc751..87e9105 100644
--- a/packages/InputDevices/res/values-ta/strings.xml
+++ b/packages/InputDevices/res/values-ta/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ஜார்ஜியன்"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"தாய் (கேட்மேனி)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"தாய் (பட்டாசொட்டே)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-te/strings.xml b/packages/InputDevices/res/values-te/strings.xml
index 2c1c1f8..4cf1b14 100644
--- a/packages/InputDevices/res/values-te/strings.xml
+++ b/packages/InputDevices/res/values-te/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"జార్జియన్"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"థాయ్ (కెడ్మనీ)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"థాయ్ (పత్తచోత్)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-th/strings.xml b/packages/InputDevices/res/values-th/strings.xml
index 3b96226..88cf752 100644
--- a/packages/InputDevices/res/values-th/strings.xml
+++ b/packages/InputDevices/res/values-th/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"ภาษาจอร์เจีย"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"ไทย (เกษมณี)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"ไทย (ปัตตะโชติ)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-tl/strings.xml b/packages/InputDevices/res/values-tl/strings.xml
index f0cd0f8..787c851 100644
--- a/packages/InputDevices/res/values-tl/strings.xml
+++ b/packages/InputDevices/res/values-tl/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-tr/strings.xml b/packages/InputDevices/res/values-tr/strings.xml
index a5c89d7..62360b5 100644
--- a/packages/InputDevices/res/values-tr/strings.xml
+++ b/packages/InputDevices/res/values-tr/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gürcüce"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tayca (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tayca (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-uk/strings.xml b/packages/InputDevices/res/values-uk/strings.xml
index dd3aab8..15b1a25 100644
--- a/packages/InputDevices/res/values-uk/strings.xml
+++ b/packages/InputDevices/res/values-uk/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Грузинська"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Тайська (кедмані)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Тайська (паттачоте)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-ur/strings.xml b/packages/InputDevices/res/values-ur/strings.xml
index 008cd10..d10c798 100644
--- a/packages/InputDevices/res/values-ur/strings.xml
+++ b/packages/InputDevices/res/values-ur/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"جارجیائی"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"تھائی (کیڈمینی)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"تھائی (پٹاچوٹے)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-uz/strings.xml b/packages/InputDevices/res/values-uz/strings.xml
index 2c1c4b0..7717909 100644
--- a/packages/InputDevices/res/values-uz/strings.xml
+++ b/packages/InputDevices/res/values-uz/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Gruzin"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tay (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tay (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-vi/strings.xml b/packages/InputDevices/res/values-vi/strings.xml
index b5a0b16b..1e3d7e4 100644
--- a/packages/InputDevices/res/values-vi/strings.xml
+++ b/packages/InputDevices/res/values-vi/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Tiếng Georgia"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Tiếng Thái (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Tiếng Thái (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zh-rCN/strings.xml b/packages/InputDevices/res/values-zh-rCN/strings.xml
index 97e75e6..5934e3b 100644
--- a/packages/InputDevices/res/values-zh-rCN/strings.xml
+++ b/packages/InputDevices/res/values-zh-rCN/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"格鲁吉亚语"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"泰语 (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"泰语 (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zh-rHK/strings.xml b/packages/InputDevices/res/values-zh-rHK/strings.xml
index 45d4b4f..dbcfd1c 100644
--- a/packages/InputDevices/res/values-zh-rHK/strings.xml
+++ b/packages/InputDevices/res/values-zh-rHK/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"格魯吉亞文"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"泰文 (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"泰文 (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zh-rTW/strings.xml b/packages/InputDevices/res/values-zh-rTW/strings.xml
index f0ea94b..c87f2ac 100644
--- a/packages/InputDevices/res/values-zh-rTW/strings.xml
+++ b/packages/InputDevices/res/values-zh-rTW/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"喬治亞文"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"泰文 (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"泰文 (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml
index 079b841..f62afba 100644
--- a/packages/InputDevices/res/values-zu/strings.xml
+++ b/packages/InputDevices/res/values-zu/strings.xml
@@ -52,4 +52,8 @@
<string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
<string name="keyboard_layout_thai_kedmanee" msgid="6637147314580760938">"Isi-Thai (Kedmanee)"</string>
<string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Isi-Thai (Pattachote)"</string>
+ <!-- no translation found for keyboard_layout_serbian_latin (3128791759390046571) -->
+ <skip />
+ <!-- no translation found for keyboard_layout_montenegrin_latin (1467832503378949945) -->
+ <skip />
</resources>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index f6efdf6..b844054 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -63,7 +63,7 @@
<string name="archive_application_text_all_users" msgid="3151229641681672580">"Да се архивира ли това приложение за всички потребители? Личните ви данни ще бъдат запазени"</string>
<string name="archive_application_text_current_user_work_profile" msgid="1450487362134779752">"Да се архивира ли това приложение в служебния ви потребителски профил? Личните ви данни ще бъдат запазени"</string>
<string name="archive_application_text_user" msgid="2586558895535581451">"Да се архивира ли това приложение за <xliff:g id="USERNAME">%1$s</xliff:g>? Личните ви данни ще бъдат запазени"</string>
- <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Искате ли да архивирате това приложение от личното си пространство? Личните ви данни ще бъдат запазени"</string>
+ <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Искате ли да архивирате това приложение от частното си пространство? Личните ви данни ще бъдат запазени"</string>
<string name="uninstall_application_text_all_users" msgid="575491774380227119">"Искате ли да деинсталирате това приложение за "<b>"всички"</b>" потребители? Приложението и данните му ще бъдат премахнати от "<b>"всички"</b>" потребители на устройството."</string>
<string name="uninstall_application_text_user" msgid="498072714173920526">"Искате ли да деинсталирате това приложение за потребителя <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
<string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Искате ли да деинсталирате това приложение от служебния си потребителски профил?"</string>
@@ -72,7 +72,7 @@
<string name="uninstall_keep_data" msgid="7002379587465487550">"Запазване на <xliff:g id="SIZE">%1$s</xliff:g> данни от приложението."</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Искате ли да изтриете това приложение?"</string>
<string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Искате ли да деинсталирате това приложение? Копието на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> също ще бъде изтрито."</string>
- <string name="uninstall_application_text_current_user_private_profile" msgid="867004464945674674">"Искате ли да деинсталирате това приложение от личното си пространство?"</string>
+ <string name="uninstall_application_text_current_user_private_profile" msgid="867004464945674674">"Искате ли да деинсталирате това приложение от частното си пространство?"</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Активни деинсталирания"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Неуспешни деинсталирания"</string>
<string name="uninstalling" msgid="8709566347688966845">"Деинсталира се..."</string>
diff --git a/packages/SettingsLib/DataStore/tests/Android.bp b/packages/SettingsLib/DataStore/tests/Android.bp
index 5d000eb..2e3b42d 100644
--- a/packages/SettingsLib/DataStore/tests/Android.bp
+++ b/packages/SettingsLib/DataStore/tests/Android.bp
@@ -26,4 +26,5 @@
instrumentation_for: "SettingsLibDataStoreShell",
coverage_libs: ["SettingsLibDataStore"],
upstream: true,
+ strict_mode: false,
}
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/Android.bp b/packages/SettingsLib/Spa/screenshot/robotests/Android.bp
index 6b8197c..c834c80 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/Android.bp
+++ b/packages/SettingsLib/Spa/screenshot/robotests/Android.bp
@@ -71,4 +71,6 @@
upstream: true,
java_resource_dirs: ["config"],
instrumentation_for: "SpaRoboApp",
+
+ strict_mode: false,
}
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 5e80604..6b6f803 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Regs: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Links <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Regs <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktief"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gestoor"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktief (net links)"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index eb1a365..6f494f0 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"ግ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>፣ ቀ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ባትሪ።"</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"ግራ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"ቀኝ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"ግራ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"ቀኝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ንቁ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ተቀምጧል"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ገቢር (ግራ ብቻ)"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index e64a742..3f39d4d 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/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>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 23bfcb5..b7dda83 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batareya."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Sol <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Sağ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Yadda saxlandı"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (yalnız sol)"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 71b7f6e..0e42066 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Levo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Levo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Levo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Sačuvano"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktivno (samo levo)"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 61ed0a1..a723223 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (левы навушнік), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (правы навушнік)."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (левы навушнік)"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (правы навушнік)"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Левы: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Правы: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Уключана"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Захавана"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Выкарыстоўваецца (толькі левы навушнік)"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 0515ed9..54fef5f 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Л: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Д: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"За ляво ухо. Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"За дясно ухо. Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Вляво: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Вдясно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активно"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Запазено"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активно (само лявото)"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index fea8137..b9961b9 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"বাঁদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ডানদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ব্যাটারি।"</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"বাঁদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"ডানদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"বাঁদিকের হেডসেটে <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> চার্জ আছে"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"ডানদিকের হেডসেটে <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> চার্জ আছে"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"চালু আছে"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"সেভ করা আছে"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"চালু আছে (শুধু বাঁদিক)"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 7dce81a..cc67420 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"E: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Esquerre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Dret: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Esquerre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Dret: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actiu"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Desat"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Actiu (només l\'esquerre)"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 20ff455..240b0f0 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -287,7 +287,7 @@
<string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Povolit odemknutí zavaděče"</string>
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Povolit odemknutí OEM?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"UPOZORNĚNÍ: Pokud bude toto nastavení zapnuto, nebudou v tomto zařízení fungovat funkce ochrany zařízení."</string>
- <string name="mock_location_app" msgid="6269380172542248304">"Vybrat aplikaci k simulování polohy"</string>
+ <string name="mock_location_app" msgid="6269380172542248304">"Vybrat aplikaci k simulování polohy"</string>
<string name="mock_location_app_not_set" msgid="6972032787262831155">"Aplikace k simulování polohy není nastavena"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"Aplikace k simulování polohy: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Sítě"</string>
@@ -602,7 +602,7 @@
<string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Pro tohoto uživatele nejsou k dispozici žádná sdílená data."</string>
<string name="shared_data_query_failure_text" msgid="3489828881998773687">"Při načítání sdílených dat došlo k chybě. Zkuste to znovu."</string>
<string name="blob_id_text" msgid="8680078988996308061">"ID sdílených dat: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
- <string name="blob_expires_text" msgid="7882727111491739331">"Platnost vyprší <xliff:g id="DATE">%s</xliff:g>"</string>
+ <string name="blob_expires_text" msgid="7882727111491739331">"Platnost skončí <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Při mazání sdílených dat došlo k chybě."</string>
<string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"Pro tato sdílená data nejsou k dispozici žádné smlouvy. Chcete je smazat?"</string>
<string name="accessor_info_title" msgid="8289823651512477787">"Aplikace, které sdílejí data"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index cfa64c0..f0fb4df 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Akku links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Akku rechts: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Akku links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Akku rechts: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Links – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Rechts – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gespeichert"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (nur links)"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index bd1b848..f549ae2 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Α: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Δ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> μπαταρία."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Αριστερά: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Δεξιά: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Αριστερό <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Δεξί <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ενεργό"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Αποθηκεύτηκε"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ενεργό (μόνο το αριστερό)"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 0167ec1..b96dd33 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"I: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>; D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Activo (solo izquierdo)"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 0899d5a..3c63119 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería. Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Izquierda <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Derecha <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Activo (solo izquierdo)"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 6be5f6c..25f002a2 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. R aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Ezkerreko aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Eskuineko aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Ezkerrekoa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Eskuinekoa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktibo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gordeta"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktibo (ezkerrekoa soilik)"</string>
@@ -239,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"Aukeratu profila"</string>
<string name="category_personal" msgid="6236798763159385225">"Pertsonalak"</string>
<string name="category_work" msgid="4014193632325996115">"Lanekoak"</string>
- <string name="category_private" msgid="4244892185452788977">"Pribatua"</string>
+ <string name="category_private" msgid="4244892185452788977">"Pribatuak"</string>
<string name="category_clone" msgid="1554511758987195974">"Klonatu"</string>
<string name="development_settings_title" msgid="140296922921597393">"Garatzaileentzako aukerak"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Gaitu garatzaileen aukerak"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index a5fe65d..399e396 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"چپ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"راست <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"فعال"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ذخیرهشده"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"فعال (فقط چپ)"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 03a6d43..d2afaac 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, O: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> virtaa."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Vasen: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Oikea: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Vasen <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Oikea <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiivinen"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Tallennettu"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiivinen (vain vasen)"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 7d2bea0..5f4480c 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Gauche : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batterie, droit : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batterie."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Gauche : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Droit : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Gauche (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>)"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Droit (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>)"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actif"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Enregistré"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Actif (gauche uniquement)"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index cc03004..874a153 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -492,7 +492,7 @@
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> para completar a carga)"</string>
<string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> (carga optimizada)"</string>
<string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> (cargando)"</string>
- <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATUS">%2$s</xliff:g> - Completa á/s <xliff:g id="TIME">%3$s</xliff:g>"</string>
+ <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATUS">%2$s</xliff:g> - Completarase á/s <xliff:g id="TIME">%3$s</xliff:g>"</string>
<string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga completa á/s <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Carga completa á/s <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Completa á/s <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index a5bf093..07eda9a 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"ડાબી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, જમણી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> બૅટરી."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"ડાબી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"જમણી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"ડાબી બાજુ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"જમણી બાજુ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"સક્રિય"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"સાચવેલું"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ચાલુ છે (માત્ર ડાબી બાજુ)"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 2aee1bc..8f83216 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/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>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 0271b09..8ce90ec 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Lijeva strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Desna strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Lijevo <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Desno <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Spremljeno"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktivno (samo lijevo)"</string>
@@ -494,7 +492,7 @@
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string>
<string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje se optimizira"</string>
<string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje"</string>
- <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – napunjeno do <xliff:g id="TIME">%3$s</xliff:g>"</string>
+ <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – bit će pun do <xliff:g id="TIME">%3$s</xliff:g>"</string>
<string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> – potpuno napunjeno do <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Potpuno napunjeno do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Napunjeno do <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 5c06624..fb142f6 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Akkumulátorok töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (bal) és <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (jobb)."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (bal)."</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (jobb)."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Bal: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Jobb: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktív"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Mentve"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktív (csak bal)"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 805284e..e7cbf2d 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Ձախ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, աջ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>։"</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Ձախ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Աջ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Ձախը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Աջը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ակտիվ է"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Պահված է"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ակտիվ է (միայն ձախ)"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 6b03ae5..82a390e 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Baterai L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Kiri: Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Kanan: Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Kiri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Kanan <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktif"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Disimpan"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktif (hanya kiri)"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index d89da77..66be184 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> rafhlöðuhleðsla."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Vinstri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Hægri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Vinstri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Hægri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Virkt"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Vistað"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Kveikt (eingöngu vinstra)"</string>
@@ -497,7 +495,7 @@
<string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATUS">%2$s</xliff:g> - Fullt kl. <xliff:g id="TIME">%3$s</xliff:g>"</string>
<string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> - Fullhlaðið kl. <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Fullhlaðið kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Fullt kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Fullhlaðin kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Óþekkt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Í hleðslu"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hröð hleðsla"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 92f9554..3714593 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"S: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> di batteria. D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> di batteria."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Sinistro: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Destro: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Sinistra: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Destra: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Attivo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Dispositivo salvato"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Attivo (solo sinistro)"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 5eb9170..c2f4a8f 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"סוללה בצד שמאל: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, סוללה בצד ימין: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"סוללה בצד שמאל: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"סוללה בצד ימין: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"אוזנייה שמאלית: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"אוזנייה ימנית: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"פעיל"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"בוצעה שמירה"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"פעיל (שמאל בלבד)"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 0efe609..a1ea070 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Сол жақ: батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. Оң жақ: батарея зарядының деңгейі — <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Сол жақ: батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Оң жақ: батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Сол: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Оң: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Қосулы"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сақталған"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Істеп тұр (тек сол жағы)"</string>
@@ -494,7 +492,7 @@
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: толық зарядталуға <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
<string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды"</string>
<string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зарядталып жатыр"</string>
- <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATUS">%2$s</xliff:g> - Заряд толуына қалған уақыт: <xliff:g id="TIME">%3$s</xliff:g>"</string>
+ <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATUS">%2$s</xliff:g> - Зарядталып болады: <xliff:g id="TIME">%3$s</xliff:g>"</string>
<string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> - Толық заряд алуға қалған уақыт: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Толық заряд алуға қалған уақыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Заряд толуына қалған уақыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 0882327..431bdf7 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"ឆ្វេង៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ស្ដាំ៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>។"</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"ឆ្វេង៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"ស្ដាំ៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"ឆ្វេង <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"ស្ដាំ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"សកម្ម"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"បានរក្សាទុក"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"សកម្ម (ខាងឆ្វេងប៉ុណ្ណោះ)"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index d47c76b..1381903 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"ಎಡ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ಬಲ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"ಎಡ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"ಬಲ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"ಎಡ ಭಾಗದ ಬ್ಯಾಟರಿ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"ಬಲ ಭಾಗದ ಬ್ಯಾಟರಿ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ಸಕ್ರಿಯ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ಸಕ್ರಿಯವಾಗಿದೆ (ಎಡಕಿವಿಯ ಸಾಧನ ಮಾತ್ರ)"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 51c8475..9cb770f 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"배터리는 왼쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, 오른쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>입니다."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"왼쪽 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"오른쪽 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"왼쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"오른쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"활성"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"저장됨"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"활성(왼쪽만)"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 0560a81..64180a9 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Батарея: L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Сол кулак – батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Оң кулак – батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Сол: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Оң: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Жигердүү"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сакталган"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Иштеп жатат (сол тарап гана)"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 201c7a0..a8c3f5a 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Akumulatora uzlādes līmenis kreisajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, labajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Akumulatora uzlādes līmenis kreisajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Akumulatora uzlādes līmenis labajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Kreisā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Labā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktīvs"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saglabāta"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ierīce aktīva (tikai kreisā auss)"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index a72a72e..630dd64 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерија, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерија."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Одлево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Оддесно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активен"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Зачувано"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активно (само лево)"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 41afe435..436326e 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"З: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Б: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батарей."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Зүүн: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Баруун: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Зүүн тал <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Баруун тал <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Идэвхтэй"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Хадгалсан"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Идэвхтэй (зөвхөн зүүн тал)"</string>
@@ -239,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>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index bd1659c..1a672c39 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Høyre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Høyre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Lagret"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (bare venstre)"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 8fc58d1..562a558 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"ବାମ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ଡାହାଣ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ବେଟେରୀ।"</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"ବାମ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"ଡାହାଣ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"ବାମ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"ଡାହାଣ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ସକ୍ରିୟ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ସେଭ କରାଯାଇଛି"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ସକ୍ରିୟ (କେବଳ ବାମ)"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 36a52b2..72e7760 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"ਖੱਬੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ਸੱਜੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ਬੈਟਰੀ।"</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"ਖੱਬੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"ਸੱਜੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"ਖੱਬੇ ਪਾਸੇ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"ਸੱਜੇ ਪਾਸੇ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ਕਿਰਿਆਸ਼ੀਲ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਖੱਬਾ)"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index da68889..3b6d758 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -234,7 +234,7 @@
<item msgid="4446831566506165093">"350%"</item>
<item msgid="6946761421234586000">"400%"</item>
</string-array>
- <string name="choose_profile" msgid="343803890897657450">"Wybierz profil"</string>
+ <string name="choose_profile" msgid="343803890897657450">"Wybierz profil konta"</string>
<string name="category_personal" msgid="6236798763159385225">"Osobiste"</string>
<string name="category_work" msgid="4014193632325996115">"Służbowe"</string>
<string name="category_private" msgid="4244892185452788977">"Prywatne"</string>
@@ -495,7 +495,7 @@
<string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – Bateria będzie pełna do <xliff:g id="TIME">%3$s</xliff:g>"</string>
<string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> – Pełne naładowanie do <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Pełne naładowanie do <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Bateria będzie pełna do <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Bateria będzie w pełni naładowana do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Nieznane"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Ładowanie"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Szybkie ładowanie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 2676ff6..d47a1f4 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvo"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ativo (apenas o esquerdo)"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 2676ff6..d47a1f4 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvo"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ativo (apenas o esquerdo)"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4c97658..1c76fdd 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Nivelul bateriei din stânga: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, dreapta: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Nivelul bateriei din stânga: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Nivelul bateriei din dreapta:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Stânga: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Dreapta: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvat"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Activ (numai stânga)"</string>
@@ -198,7 +196,7 @@
<string name="launch_defaults_some" msgid="3631650616557252926">"Unele valori prestabilite sunt configurate"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"Nu este configurată nicio valoare prestabilită"</string>
<string name="tts_settings" msgid="8130616705989351312">"Setări redare vocală a textului"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"Rezultatul redării vocale a textului"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"Setări pentru redarea vocală a textului"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"Ritmul vorbirii"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"Viteza cu care este vorbit textul"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"Înălțime"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 505a1ec..2972e61 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (Л), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (П)."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (Л)"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (П)"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Левый <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Правый <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активно"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сохранено"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Используется (только левый)"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 6e4b5f9..9f1aca6 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"බැටරිය ව: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ද: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"වම: බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"දකුණ: බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"වම <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"දකුණ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ක්රියාකාරී"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"සුරැකිණි"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"සක්රිය (වම පමණි)"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 64c1113..db8301a 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Ľ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batérie."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Ľavá strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Pravá strana: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Ľavé: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Pravé: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktívne"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Uložené"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktívne (iba ľavé)"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 0288ec2..c33e425 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Majtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> bateri, djathtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> bateri."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Majtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Djathtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Majtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Djathtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Të ruajtura"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktive (vetëm majtas)"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 927b8e4..fa94c2e 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активан"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сачувано"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активно (само лево)"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 7c6a832..04c8a40 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Vänster: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Höger: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Vänster: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Höger <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Sparad"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (endast vänster)"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 4b67011..ff62ba0 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"இடது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, வலது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"இடது: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"வலது: - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"இடதுபுறம்: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"வலதுபுறம்: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"செயலில் உள்ளது"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"சேமிக்கப்பட்டது"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"செயலில் உள்ளது (இடதுபுறம் மட்டும்)"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 97d20bf..c79db5f 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pil seviyesi."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Sol <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Sağ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Etkin"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Kaydedildi"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Etkin (yalnızca sol taraf)"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index ab1e7f6..0400e0e 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Лівий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, правий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> заряду акумулятора."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Лівий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Правий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Ліва частина: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Права частина: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активовано"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Збережено"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активовано (лише лівий)"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index f0a89b3..f285086 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"Quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (L), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (R)."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (chap)"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> (oʻng)."</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Chapda: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Oʻngda: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Faol"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saqlangan"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Faol (faqat chap)"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index d85449e..d7cc91e 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -492,10 +492,10 @@
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> nữa là pin đầy"</string>
<string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Quá trình sạc được tối ưu hoá"</string>
<string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Đang sạc"</string>
- <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – Pin sẽ đầy vào <xliff:g id="TIME">%3$s</xliff:g>"</string>
- <string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> – Pin sẽ đầy vào <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Pin sẽ đầy vào <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Pin sẽ đầy vào <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – Đến <xliff:g id="TIME">%3$s</xliff:g> pin sẽ đầy"</string>
+ <string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> – Đến <xliff:g id="TIME">%2$s</xliff:g> pin sẽ đầy"</string>
+ <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Đến <xliff:g id="TIME">%1$s</xliff:g> pin sẽ đầy"</string>
+ <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Đến <xliff:g id="TIME">%1$s</xliff:g> pin sẽ đầy"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Không xác định"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Đang sạc"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Đang sạc nhanh"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 20fd651..7a355b9 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"左侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>,右侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"左侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"右侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"左耳机电池电量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"右耳机电池电量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"已保存的设备"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"使用中(仅左耳助听器)"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 556c0af..d09a281 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -495,7 +495,7 @@
<string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATUS">%2$s</xliff:g> - 在 <xliff:g id="TIME">%3$s</xliff:g>前充滿電"</string>
<string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> • 在 <xliff:g id="TIME">%2$s</xliff:g>前充滿電"</string>
<string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"在 <xliff:g id="TIME">%1$s</xliff:g>前充滿電"</string>
- <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"在 <xliff:g id="TIME">%1$s</xliff:g>前充滿電"</string>
+ <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"<xliff:g id="TIME">%1$s</xliff:g> 前充滿電"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 063d148..0a0fdff 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -103,10 +103,8 @@
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ibhethri."</string>
<string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Kwesobunxele: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri"</string>
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Kwesokudla: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri"</string>
- <!-- no translation found for tv_bluetooth_battery_level_untethered_left (337629670583744410) -->
- <skip />
- <!-- no translation found for tv_bluetooth_battery_level_untethered_right (8610019317279155595) -->
- <skip />
+ <string name="tv_bluetooth_battery_level_untethered_left" msgid="337629670583744410">"Kwesokunxele <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="tv_bluetooth_battery_level_untethered_right" msgid="8610019317279155595">"Kwesokudla <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Iyasebenza"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Ilondoloziwe"</string>
<string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Iyasebenza (ngakwesokunxele kuphela)"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/view/accessibility/data/repository/CaptioningRepository.kt b/packages/SettingsLib/src/com/android/settingslib/view/accessibility/data/repository/CaptioningRepository.kt
index 5bcb82d..0b71d25 100644
--- a/packages/SettingsLib/src/com/android/settingslib/view/accessibility/data/repository/CaptioningRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/view/accessibility/data/repository/CaptioningRepository.kt
@@ -27,6 +27,7 @@
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -62,16 +63,18 @@
captioningChanges
.filterIsInstance(CaptioningChange.IsSystemAudioCaptioningEnabled::class)
.map { it.isEnabled }
+ .onStart { emit(captioningManager.isSystemAudioCaptioningEnabled) }
.stateIn(
coroutineScope,
SharingStarted.WhileSubscribed(),
- captioningManager.isSystemAudioCaptioningEnabled
+ captioningManager.isSystemAudioCaptioningEnabled,
)
override val isSystemAudioCaptioningUiEnabled: StateFlow<Boolean> =
captioningChanges
.filterIsInstance(CaptioningChange.IsSystemUICaptioningEnabled::class)
.map { it.isEnabled }
+ .onStart { emit(captioningManager.isSystemAudioCaptioningUiEnabled) }
.stateIn(
coroutineScope,
SharingStarted.WhileSubscribed(),
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 3b84333..8204569 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
@@ -16,9 +16,13 @@
package com.android.settingslib.volume.data.repository
+import android.content.ContentResolver
+import android.database.ContentObserver
import android.media.AudioDeviceInfo
import android.media.AudioManager
import android.media.AudioManager.OnCommunicationDeviceChangedListener
+import android.provider.Settings
+import androidx.concurrent.futures.DirectExecutor
import com.android.internal.util.ConcurrentUtils
import com.android.settingslib.volume.shared.AudioManagerEventsReceiver
import com.android.settingslib.volume.shared.model.AudioManagerEvent
@@ -33,12 +37,13 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -84,17 +89,31 @@
class AudioRepositoryImpl(
private val audioManagerEventsReceiver: AudioManagerEventsReceiver,
private val audioManager: AudioManager,
+ private val contentResolver: ContentResolver,
private val backgroundCoroutineContext: CoroutineContext,
private val coroutineScope: CoroutineScope,
) : AudioRepository {
+ private val streamSettingNames: Map<AudioStream, String> =
+ mapOf(
+ AudioStream(AudioManager.STREAM_VOICE_CALL) to Settings.System.VOLUME_VOICE,
+ AudioStream(AudioManager.STREAM_SYSTEM) to Settings.System.VOLUME_SYSTEM,
+ AudioStream(AudioManager.STREAM_RING) to Settings.System.VOLUME_RING,
+ AudioStream(AudioManager.STREAM_MUSIC) to Settings.System.VOLUME_MUSIC,
+ AudioStream(AudioManager.STREAM_ALARM) to Settings.System.VOLUME_ALARM,
+ AudioStream(AudioManager.STREAM_NOTIFICATION) to Settings.System.VOLUME_NOTIFICATION,
+ AudioStream(AudioManager.STREAM_BLUETOOTH_SCO) to Settings.System.VOLUME_BLUETOOTH_SCO,
+ AudioStream(AudioManager.STREAM_ACCESSIBILITY) to Settings.System.VOLUME_ACCESSIBILITY,
+ AudioStream(AudioManager.STREAM_ASSISTANT) to Settings.System.VOLUME_ASSISTANT,
+ )
+
override val mode: StateFlow<Int> =
callbackFlow {
- val listener =
- AudioManager.OnModeChangedListener { newMode -> launch { send(newMode) } }
+ val listener = AudioManager.OnModeChangedListener { newMode -> trySend(newMode) }
audioManager.addOnModeChangedListener(ConcurrentUtils.DIRECT_EXECUTOR, listener)
awaitClose { audioManager.removeOnModeChangedListener(listener) }
}
+ .onStart { emit(audioManager.mode) }
.flowOn(backgroundCoroutineContext)
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), audioManager.mode)
@@ -102,6 +121,7 @@
audioManagerEventsReceiver.events
.filterIsInstance(AudioManagerEvent.InternalRingerModeChanged::class)
.map { RingerMode(audioManager.ringerModeInternal) }
+ .onStart { emit(RingerMode(audioManager.ringerModeInternal)) }
.flowOn(backgroundCoroutineContext)
.stateIn(
coroutineScope,
@@ -122,6 +142,7 @@
}
.filterNotNull()
.map { audioManager.communicationDevice }
+ .onStart { emit(audioManager.communicationDevice) }
.flowOn(backgroundCoroutineContext)
.stateIn(
coroutineScope,
@@ -130,17 +151,18 @@
)
override fun getAudioStream(audioStream: AudioStream): Flow<AudioStreamModel> {
- return audioManagerEventsReceiver.events
- .filter {
- if (it is StreamAudioManagerEvent) {
- it.audioStream == audioStream
- } else {
- true
- }
- }
+ return merge(
+ audioManagerEventsReceiver.events.filter {
+ if (it is StreamAudioManagerEvent) {
+ it.audioStream == audioStream
+ } else {
+ true
+ }
+ },
+ volumeSettingChanges(audioStream),
+ )
.map { getCurrentAudioStream(audioStream) }
.onStart { emit(getCurrentAudioStream(audioStream)) }
- .conflate()
.flowOn(backgroundCoroutineContext)
}
@@ -195,4 +217,19 @@
// return STREAM_VOICE_CALL in getAudioStream
audioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL)
}
+
+ private fun volumeSettingChanges(audioStream: AudioStream): Flow<Unit> {
+ val uri = streamSettingNames[audioStream]?.let(Settings.System::getUriFor)
+ uri ?: return emptyFlow()
+ return callbackFlow {
+ val observer =
+ object : ContentObserver(DirectExecutor.INSTANCE, 0) {
+ override fun onChange(selfChange: Boolean) {
+ launch { send(Unit) }
+ }
+ }
+ contentResolver.registerContentObserver(uri, false, observer)
+ awaitClose { contentResolver.unregisterContentObserver(observer) }
+ }
+ }
}
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 8700680..683759d 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
@@ -16,6 +16,8 @@
package com.android.settingslib.volume.data.repository
+import android.content.ContentResolver
+import android.database.ContentObserver
import android.media.AudioDeviceInfo
import android.media.AudioManager
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -38,6 +40,7 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Captor
import org.mockito.Mock
@@ -55,9 +58,11 @@
@Captor
private lateinit var communicationDeviceListenerCaptor:
ArgumentCaptor<AudioManager.OnCommunicationDeviceChangedListener>
+ @Captor private lateinit var contentObserver: ArgumentCaptor<ContentObserver>
@Mock private lateinit var audioManager: AudioManager
@Mock private lateinit var communicationDevice: AudioDeviceInfo
+ @Mock private lateinit var contentResolver: ContentResolver
private val eventsReceiver = FakeAudioManagerEventsReceiver()
private val volumeByStream: MutableMap<Int, Int> = mutableMapOf()
@@ -80,6 +85,7 @@
val streamType = it.arguments[0] as Int
volumeByStream[it.arguments[0] as Int] = it.arguments[1] as Int
triggerEvent(AudioManagerEvent.StreamVolumeChanged(AudioStream(streamType)))
+ triggerSettingChange()
}
`when`(audioManager.adjustStreamVolume(anyInt(), anyInt(), anyInt())).then {
val streamType = it.arguments[0] as Int
@@ -100,6 +106,7 @@
AudioRepositoryImpl(
eventsReceiver,
audioManager,
+ contentResolver,
testScope.testScheduler,
testScope.backgroundScope,
)
@@ -254,6 +261,12 @@
modeListenerCaptor.value.onModeChanged(mode)
}
+ private fun triggerSettingChange(selfChange: Boolean = false) {
+ verify(contentResolver)
+ .registerContentObserver(any(), anyBoolean(), contentObserver.capture())
+ contentObserver.value.onChange(selfChange)
+ }
+
private fun triggerEvent(event: AudioManagerEvent) {
testScope.launch { eventsReceiver.triggerEvent(event) }
}
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index e125083..397fab1 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -64,6 +64,8 @@
timeout: 36000,
},
upstream: true,
+
+ strict_mode: false,
}
java_genrule {
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 780a099..36bad5e 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -960,7 +960,7 @@
}
flag {
- name: "media_controls_user_initiated_dismiss"
+ name: "media_controls_user_initiated_deleteintent"
namespace: "systemui"
description: "Only dismiss media notifications when the control was removed by the user."
bug: "335875159"
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
index 54a98dd..8195df3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
@@ -16,6 +16,8 @@
package com.android.systemui.qs.ui.composable
+import android.view.ViewGroup
+import android.widget.FrameLayout
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
@@ -24,6 +26,7 @@
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
@@ -164,11 +167,8 @@
state: () -> QSSceneAdapter.State,
modifier: Modifier = Modifier,
) {
- val qsView by qsSceneAdapter.qsView.collectAsStateWithLifecycle(null)
- val isCustomizing by
- qsSceneAdapter.isCustomizerShowing.collectAsStateWithLifecycle(
- qsSceneAdapter.isCustomizerShowing.value
- )
+ val qsView by qsSceneAdapter.qsView.collectAsStateWithLifecycle()
+ val isCustomizing by qsSceneAdapter.isCustomizerShowing.collectAsStateWithLifecycle()
QuickSettingsTheme {
val context = LocalContext.current
@@ -180,15 +180,34 @@
qsView?.let { view ->
Box(
modifier =
- modifier.fillMaxWidth().thenIf(isCustomizing) { Modifier.fillMaxHeight() }
+ modifier
+ .fillMaxWidth()
+ .thenIf(isCustomizing) { Modifier.fillMaxHeight() }
+ .drawWithContent {
+ qsSceneAdapter.applyLatestExpansionAndSquishiness()
+ drawContent()
+ }
) {
AndroidView(
modifier = Modifier.fillMaxWidth(),
- factory = { _ ->
+ factory = { context ->
qsSceneAdapter.setState(state())
- view
+ FrameLayout(context).apply {
+ (view.parent as? ViewGroup)?.removeView(view)
+ addView(view)
+ }
},
- update = { qsSceneAdapter.setState(state()) }
+ // When the view changes (e.g. due to a theme change), this will be recomposed
+ // if needed and the new view will be attached to the FrameLayout here.
+ update = {
+ qsSceneAdapter.setState(state())
+ if (view.parent != it) {
+ it.removeAllViews()
+ (view.parent as? ViewGroup)?.removeView(view)
+ it.addView(view)
+ }
+ },
+ onRelease = { it.removeAllViews() }
)
}
}
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 9d689fc..33a630c 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
@@ -25,6 +25,7 @@
import androidx.compose.foundation.clipScrollableContainer
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -42,6 +43,7 @@
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -67,6 +69,7 @@
import com.android.compose.animation.scene.animateSceneFloatAsState
import com.android.compose.modifiers.padding
import com.android.compose.modifiers.thenIf
+import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation
import com.android.systemui.common.ui.compose.windowinsets.LocalDisplayCutout
@@ -235,6 +238,10 @@
val shouldPunchHoleBehindScrim =
layoutState.isTransitioningBetween(Scenes.Gone, Scenes.Shade) ||
layoutState.isTransitioningBetween(Scenes.Lockscreen, Scenes.Shade)
+ // Media is visible and we are in landscape on a small height screen
+ val mediaInRow =
+ isMediaVisible &&
+ LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Compact
Box(
modifier =
@@ -274,22 +281,39 @@
createBatteryMeterViewController = createBatteryMeterViewController,
statusBarIconController = statusBarIconController,
)
- Box(Modifier.element(QuickSettings.Elements.QuickQuickSettings)) {
- QuickSettings(
- viewModel.qsSceneAdapter,
- { viewModel.qsSceneAdapter.qqsHeight },
- isSplitShade = false,
- squishiness = { tileSquishiness },
+
+ val content: @Composable (Modifier) -> Unit = { modifier ->
+ Box(
+ Modifier.element(QuickSettings.Elements.QuickQuickSettings)
+ .then(modifier)
+ ) {
+ QuickSettings(
+ viewModel.qsSceneAdapter,
+ { viewModel.qsSceneAdapter.qqsHeight },
+ isSplitShade = false,
+ squishiness = { tileSquishiness },
+ )
+ }
+
+ MediaCarousel(
+ isVisible = isMediaVisible,
+ mediaHost = mediaHost,
+ modifier = Modifier.fillMaxWidth().then(modifier),
+ carouselController = mediaCarouselController,
)
}
- MediaCarousel(
- isVisible = isMediaVisible,
- mediaHost = mediaHost,
- modifier = Modifier.fillMaxWidth(),
- carouselController = mediaCarouselController,
- )
-
+ if (!mediaInRow) {
+ content(Modifier)
+ } else {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = spacedBy(16.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ content(Modifier.weight(1f))
+ }
+ }
Spacer(modifier = Modifier.height(16.dp))
}
},
diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md
index b2424f4..ade5171 100644
--- a/packages/SystemUI/docs/demo_mode.md
+++ b/packages/SystemUI/docs/demo_mode.md
@@ -22,42 +22,45 @@
<br/>
Commands are sent as string extras with key ```command``` (required). Possible values are:
-| Command | Subcommand | Argument | Description
-| --- | --- | --- | ---
-| ```enter``` | | | Enters demo mode, bar state allowed to be modified (for convenience, any of the other non-exit commands will automatically flip demo mode on, no need to call this explicitly in practice)
-| ```exit``` | | | Exits demo mode, bars back to their system-driven state
-| ```battery``` | | | Control the battery display
-| | ```level``` | | Sets the battery level (0 - 100)
-| | ```plugged``` | | Sets charging state (```true```, ```false```)
-| | ```powersave``` | | Sets power save mode (```true```, ```anything else```)
-| ```network``` | | | Control the RSSI display
-| | ```airplane``` | | ```show``` to show icon, any other value to hide
-| | ```fully``` | | Sets MCS state to fully connected (```true```, ```false```)
-| | ```wifi``` | | ```show``` to show icon, any other value to hide
-| | | ```level``` | Sets wifi level (null or 0-4)
-| | ```mobile``` | | ```show``` to show icon, any other value to hide
-| | | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
-| | | ```level``` | Sets mobile signal strength level (null or 0-4)
-| | ```carriernetworkchange``` | | Sets mobile signal icon to carrier network change UX when disconnected (```show``` to show icon, any other value to hide)
-| | ```sims``` | | Sets the number of sims (1-8)
-| | ```nosim``` | | ```show``` to show icon, any other value to hide
-| ```bars``` | | | Control the visual style of the bars (opaque, translucent, etc)
-| | ```mode``` | | Sets the bars visual style (opaque, translucent, semi-transparent)
-| ```status``` | | | Control the system status icons
-| | ```volume``` | | Sets the icon in the volume slot (```silent```, ```vibrate```, any other value to hide)
-| | ```bluetooth``` | | Sets the icon in the bluetooth slot (```connected```, ```disconnected```, any other value to hide)
-| | ```location``` | | Sets the icon in the location slot (```show```, any other value to hide)
-| | ```alarm``` | | Sets the icon in the alarm_clock slot (```show```, any other value to hide)
-| | ```sync``` | | Sets the icon in the sync_active slot (```show```, any other value to hide)
-| | ```tty``` | | Sets the icon in the tty slot (```show```, any other value to hide)
-| | ```eri``` | | Sets the icon in the cdma_eri slot (```show```, any other value to hide)
-| | ```mute``` | | Sets the icon in the mute slot (```show```, any other value to hide)
-| | ```speakerphone``` | | Sets the icon in the speakerphone slot (```show```, any other value to hide)
-| ```notifications``` | | | Control the notification icons
-| | ```visible``` | | ```false``` to hide the notification icons, any other value to show
-| ```clock``` | | | Control the clock display
-| | ```millis``` | | Sets the time in millis
-| | ```hhmm``` | | Sets the time in hh:mm
+| Command | Subcommand | Argument | Description
+| --- |----------------------------|------------------| ---
+| ```enter``` | | | Enters demo mode, bar state allowed to be modified (for convenience, any of the other non-exit commands will automatically flip demo mode on, no need to call this explicitly in practice)
+| ```exit``` | | | Exits demo mode, bars back to their system-driven state
+| ```battery``` | | | Control the battery display
+| | ```level``` | | Sets the battery level (0 - 100)
+| | ```plugged``` | | Sets charging state (```true```, ```false```)
+| | ```powersave``` | | Sets power save mode (```true```, ```anything else```)
+| ```network``` | | | Control the RSSI display
+| | ```airplane``` | | ```show``` to show icon, any other value to hide
+| | ```fully``` | | Sets MCS state to fully connected (```true```, ```false```)
+| | ```wifi``` | | ```show``` to show icon, any other value to hide
+| | | ```level``` | Sets wifi level (null or 0-4)
+| | ```mobile``` | | ```show``` to show icon, any other value to hide
+| | | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
+| | | ```level``` | Sets mobile signal strength level (null or 0-4)
+| | ```satellite``` | | ```show``` to show icon, any other value to hide
+| | | ```connection``` | ```connected```, ```off```, ```on```, or ```unknown``` (matches SatelliteConnectionState enum)
+| | | ```level``` | Sets satellite signal strength level (0-4)
+| | ```carriernetworkchange``` | | Sets mobile signal icon to carrier network change UX when disconnected (```show``` to show icon, any other value to hide)
+| | ```sims``` | | Sets the number of sims (1-8)
+| | ```nosim``` | | ```show``` to show icon, any other value to hide
+| ```bars``` | | | Control the visual style of the bars (opaque, translucent, etc)
+| | ```mode``` | | Sets the bars visual style (opaque, translucent, semi-transparent)
+| ```status``` | | | Control the system status icons
+| | ```volume``` | | Sets the icon in the volume slot (```silent```, ```vibrate```, any other value to hide)
+| | ```bluetooth``` | | Sets the icon in the bluetooth slot (```connected```, ```disconnected```, any other value to hide)
+| | ```location``` | | Sets the icon in the location slot (```show```, any other value to hide)
+| | ```alarm``` | | Sets the icon in the alarm_clock slot (```show```, any other value to hide)
+| | ```sync``` | | Sets the icon in the sync_active slot (```show```, any other value to hide)
+| | ```tty``` | | Sets the icon in the tty slot (```show```, any other value to hide)
+| | ```eri``` | | Sets the icon in the cdma_eri slot (```show```, any other value to hide)
+| | ```mute``` | | Sets the icon in the mute slot (```show```, any other value to hide)
+| | ```speakerphone``` | | Sets the icon in the speakerphone slot (```show```, any other value to hide)
+| ```notifications``` | | | Control the notification icons
+| | ```visible``` | | ```false``` to hide the notification icons, any other value to show
+| ```clock``` | | | Control the clock display
+| | ```millis``` | | Sets the time in millis
+| | ```hhmm``` | | Sets the time in hh:mm
## Examples
Enter demo mode
@@ -90,6 +93,15 @@
```
+Show the satellite icon
+
+```
+# Sets mobile to be out-of-service, which is required for satellite to show
+adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile show -e level 0
+# Sets satellite to be connected
+adb shell am broadcast -a com.android.systemui.demo -e command network -e satellite show -e level 4 -e connection connected
+```
+
Show the silent volume icon
```
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 0ab0959..e61b2d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -21,6 +21,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
@@ -35,6 +36,8 @@
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.notificationShadeWindowController
+import com.android.systemui.statusbar.phone.centralSurfaces
+import com.android.systemui.statusbar.phone.centralSurfacesOptional
import com.android.systemui.testKosmos
import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
@@ -49,6 +52,7 @@
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -67,6 +71,7 @@
CommunalSceneStartable(
dockManager = dockManager,
communalInteractor = communalInteractor,
+ communalSceneInteractor = communalSceneInteractor,
keyguardTransitionInteractor = keyguardTransitionInteractor,
keyguardInteractor = keyguardInteractor,
systemSettings = fakeSettings,
@@ -74,6 +79,7 @@
applicationScope = applicationCoroutineScope,
bgScope = applicationCoroutineScope,
mainDispatcher = testDispatcher,
+ centralSurfacesOpt = centralSurfacesOptional,
)
.apply { start() }
@@ -90,9 +96,9 @@
fun keyguardGoesAway_forceBlankScene() =
with(kosmos) {
testScope.runTest {
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
fakeKeyguardTransitionRepository.sendTransitionSteps(
@@ -110,7 +116,7 @@
fun deviceDocked_forceCommunalScene() =
with(kosmos) {
testScope.runTest {
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Blank)
updateDocked(true)
@@ -127,8 +133,9 @@
fun occluded_forceBlankScene() =
with(kosmos) {
testScope.runTest {
- val scene by collectLastValue(communalInteractor.desiredScene)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ whenever(centralSurfaces.isLaunchingActivityOverLockscreen).thenReturn(false)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
updateDocked(true)
@@ -142,10 +149,29 @@
}
@Test
+ fun occluded_doesNotForceBlankSceneIfLaunchingActivityOverLockscreen() =
+ with(kosmos) {
+ testScope.runTest {
+ whenever(centralSurfaces.isLaunchingActivityOverLockscreen).thenReturn(true)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
+ assertThat(scene).isEqualTo(CommunalScenes.Communal)
+
+ updateDocked(true)
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.OCCLUDED,
+ testScope = this
+ )
+ assertThat(scene).isEqualTo(CommunalScenes.Communal)
+ }
+ }
+
+ @Test
fun deviceDocked_doesNotForceCommunalIfTransitioningFromCommunal() =
with(kosmos) {
testScope.runTest {
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Blank)
updateDocked(true)
@@ -162,8 +188,8 @@
fun deviceAsleep_forceBlankSceneAfterTimeout() =
with(kosmos) {
testScope.runTest {
- val scene by collectLastValue(communalInteractor.desiredScene)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
fakeKeyguardTransitionRepository.sendTransitionSteps(
@@ -183,8 +209,8 @@
fun deviceAsleep_wakesUpBeforeTimeout_noChangeInScene() =
with(kosmos) {
testScope.runTest {
- val scene by collectLastValue(communalInteractor.desiredScene)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
fakeKeyguardTransitionRepository.sendTransitionSteps(
@@ -212,8 +238,8 @@
fun dockingOnLockscreen_forcesCommunal() =
with(kosmos) {
testScope.runTest {
- communalInteractor.changeScene(CommunalScenes.Blank)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Blank)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
// device is docked while on the lockscreen
fakeKeyguardTransitionRepository.sendTransitionSteps(
@@ -234,8 +260,8 @@
fun dockingOnLockscreen_doesNotForceCommunalIfDreamStarts() =
with(kosmos) {
testScope.runTest {
- communalInteractor.changeScene(CommunalScenes.Blank)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ communalSceneInteractor.changeScene(CommunalScenes.Blank)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
// device is docked while on the lockscreen
fakeKeyguardTransitionRepository.sendTransitionSteps(
@@ -266,9 +292,9 @@
testScope.runTest {
// Device is dreaming and on communal.
updateDreaming(true)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
// Scene times out back to blank after the screen timeout.
@@ -283,11 +309,11 @@
testScope.runTest {
// Device is not dreaming and on communal.
updateDreaming(false)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
// Scene stays as Communal
advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
}
}
@@ -298,9 +324,9 @@
testScope.runTest {
// Device is dreaming and on communal.
updateDreaming(true)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
// Wait a bit, but not long enough to timeout.
@@ -321,9 +347,9 @@
testScope.runTest {
// Device is on communal, but not dreaming.
updateDreaming(false)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
// Wait a bit, but not long enough to timeout, then start dreaming.
@@ -342,11 +368,11 @@
with(kosmos) {
testScope.runTest {
// Device is on communal.
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
// Device stays on the hub after the timeout since we're not dreaming.
advanceTimeBy(SCREEN_TIMEOUT.milliseconds * 2)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
// Start dreaming.
@@ -363,9 +389,9 @@
testScope.runTest {
// Device is dreaming and on communal.
updateDreaming(true)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
// Wait a bit, but not long enough to timeout.
@@ -392,9 +418,9 @@
// Device is dreaming and on communal.
updateDreaming(true)
- communalInteractor.changeScene(CommunalScenes.Communal)
+ communalSceneInteractor.changeScene(CommunalScenes.Communal)
- val scene by collectLastValue(communalInteractor.desiredScene)
+ val scene by collectLastValue(communalSceneInteractor.currentScene)
assertThat(scene).isEqualTo(CommunalScenes.Communal)
// Scene times out back to blank after the screen timeout.
@@ -421,12 +447,6 @@
runCurrent()
}
- private suspend fun TestScope.enableCommunal() =
- with(kosmos) {
- setCommunalAvailable(true)
- runCurrent()
- }
-
companion object {
private const val SCREEN_TIMEOUT = 1000
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
index 2d78a9b..45e7d8a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
@@ -39,7 +39,7 @@
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val underTest by lazy {
- CommunalRepositoryImpl(
+ CommunalSceneRepositoryImpl(
kosmos.applicationCoroutineScope,
kosmos.sceneDataSource,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
index 5a7cbf6..cebcbc9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
@@ -21,9 +21,9 @@
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.data.repository.FakeCommunalRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -48,7 +48,7 @@
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
- private lateinit var communalRepository: FakeCommunalRepository
+ private lateinit var communalRepository: FakeCommunalSceneRepository
private lateinit var widgetRepository: FakeCommunalWidgetRepository
private lateinit var keyguardRepository: FakeKeyguardRepository
@@ -56,7 +56,7 @@
@Before
fun setUp() {
- communalRepository = kosmos.fakeCommunalRepository
+ communalRepository = kosmos.fakeCommunalSceneRepository
widgetRepository = kosmos.fakeCommunalWidgetRepository
keyguardRepository = kosmos.fakeKeyguardRepository
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 83227e1..ffa63d8 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
@@ -39,15 +39,16 @@
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.FakeCommunalRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
import com.android.systemui.communal.data.repository.fakeCommunalMediaRepository
import com.android.systemui.communal.data.repository.fakeCommunalPrefsRepository
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
@@ -111,7 +112,7 @@
private val testScope = kosmos.testScope
private lateinit var tutorialRepository: FakeCommunalTutorialRepository
- private lateinit var communalRepository: FakeCommunalRepository
+ private lateinit var communalRepository: FakeCommunalSceneRepository
private lateinit var mediaRepository: FakeCommunalMediaRepository
private lateinit var widgetRepository: FakeCommunalWidgetRepository
private lateinit var smartspaceRepository: FakeSmartspaceRepository
@@ -131,7 +132,7 @@
MockitoAnnotations.initMocks(this)
tutorialRepository = kosmos.fakeCommunalTutorialRepository
- communalRepository = kosmos.fakeCommunalRepository
+ communalRepository = kosmos.fakeCommunalSceneRepository
mediaRepository = kosmos.fakeCommunalMediaRepository
widgetRepository = kosmos.fakeCommunalWidgetRepository
smartspaceRepository = kosmos.fakeSmartspaceRepository
@@ -508,30 +509,6 @@
}
@Test
- fun desiredScene_communalNotAvailable_returnsBlank() =
- testScope.runTest {
- kosmos.setCommunalAvailable(true)
- runCurrent()
-
- val desiredScene by collectLastValue(underTest.desiredScene)
-
- underTest.changeScene(CommunalScenes.Communal)
- assertThat(desiredScene).isEqualTo(CommunalScenes.Communal)
-
- kosmos.setCommunalAvailable(false)
- runCurrent()
-
- // Scene returns blank when communal is not available.
- assertThat(desiredScene).isEqualTo(CommunalScenes.Blank)
-
- kosmos.setCommunalAvailable(true)
- runCurrent()
-
- // After re-enabling, scene goes back to Communal.
- assertThat(desiredScene).isEqualTo(CommunalScenes.Communal)
- }
-
- @Test
fun transitionProgress_onTargetScene_fullProgress() =
testScope.runTest {
val targetScene = CommunalScenes.Blank
@@ -545,7 +522,8 @@
underTest.setTransitionState(transitionState)
// We're on the target scene.
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Idle(targetScene))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(targetScene))
}
@Test
@@ -563,7 +541,8 @@
underTest.setTransitionState(transitionState)
// Transition progress is still idle, but we're not on the target scene.
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Idle(currentScene))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(currentScene))
}
@Test
@@ -581,7 +560,8 @@
underTest.setTransitionState(transitionState)
// Progress starts at 0.
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Idle(currentScene))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(currentScene))
val progress = MutableStateFlow(0f)
transitionState =
@@ -599,16 +579,18 @@
// Partially transition.
progress.value = .4f
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Transition(.4f))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Transition(.4f))
// Transition is at full progress.
progress.value = 1f
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Transition(1f))
+ assertThat(transitionProgress).isEqualTo(CommunalTransitionProgressModel.Transition(1f))
// Transition finishes.
transitionState = MutableStateFlow(ObservableTransitionState.Idle(targetScene))
underTest.setTransitionState(transitionState)
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Idle(targetScene))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(targetScene))
}
@Test
@@ -626,7 +608,8 @@
underTest.setTransitionState(transitionState)
// Progress starts at 0.
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Idle(currentScene))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(currentScene))
val progress = MutableStateFlow(0f)
transitionState =
@@ -646,16 +629,19 @@
progress.value = .4f
// This is a transition we don't care about the progress of.
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.OtherTransition)
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.OtherTransition)
// Transition is at full progress.
progress.value = 1f
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.OtherTransition)
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.OtherTransition)
// Transition finishes.
transitionState = MutableStateFlow(ObservableTransitionState.Idle(targetScene))
underTest.setTransitionState(transitionState)
- assertThat(transitionProgress).isEqualTo(CommunalTransitionProgress.Idle(targetScene))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(targetScene))
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
new file mode 100644
index 0000000..aad2e60
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
@@ -0,0 +1,227 @@
+/*
+ * 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.communal.domain.interactor
+
+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.communal.data.repository.communalSceneRepository
+import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalSceneInteractorTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private val repository = kosmos.communalSceneRepository
+ private val underTest by lazy { kosmos.communalSceneInteractor }
+
+ @Test
+ fun changeScene() =
+ testScope.runTest {
+ val currentScene by collectLastValue(underTest.currentScene)
+ assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
+
+ underTest.changeScene(CommunalScenes.Communal)
+ assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
+ }
+
+ @Test
+ fun snapToScene() =
+ testScope.runTest {
+ val currentScene by collectLastValue(underTest.currentScene)
+ assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
+
+ underTest.snapToScene(CommunalScenes.Communal)
+ assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
+ }
+
+ @Test
+ fun transitionProgress_fullProgress() =
+ testScope.runTest {
+ val transitionProgress by
+ collectLastValue(underTest.transitionProgressToScene(CommunalScenes.Blank))
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(CommunalScenes.Blank))
+
+ val transitionState =
+ MutableStateFlow<ObservableTransitionState>(
+ ObservableTransitionState.Idle(CommunalScenes.Communal)
+ )
+ underTest.setTransitionState(transitionState)
+
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(CommunalScenes.Communal))
+ }
+
+ @Test
+ fun transitionProgress_transitioningAwayFromTrackedScene() =
+ testScope.runTest {
+ val transitionProgress by
+ collectLastValue(underTest.transitionProgressToScene(CommunalScenes.Blank))
+
+ val progress = MutableStateFlow(0f)
+ underTest.setTransitionState(
+ MutableStateFlow(
+ ObservableTransitionState.Transition(
+ fromScene = CommunalScenes.Blank,
+ toScene = CommunalScenes.Communal,
+ currentScene = flowOf(CommunalScenes.Communal),
+ progress = progress,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ )
+ )
+
+ // Partially transition.
+ progress.value = .4f
+
+ // This is a transition we don't care about the progress of.
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.OtherTransition)
+
+ // Transition is at full progress.
+ progress.value = 1f
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.OtherTransition)
+
+ // Transition finishes.
+ underTest.setTransitionState(
+ MutableStateFlow(ObservableTransitionState.Idle(CommunalScenes.Communal))
+ )
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(CommunalScenes.Communal))
+ }
+
+ @Test
+ fun transitionProgress_transitioningToTrackedScene() =
+ testScope.runTest {
+ val transitionProgress by
+ collectLastValue(underTest.transitionProgressToScene(CommunalScenes.Communal))
+
+ val progress = MutableStateFlow(0f)
+ underTest.setTransitionState(
+ MutableStateFlow(
+ ObservableTransitionState.Transition(
+ fromScene = CommunalScenes.Blank,
+ toScene = CommunalScenes.Communal,
+ currentScene = flowOf(CommunalScenes.Communal),
+ progress = progress,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ )
+ )
+
+ // Partially transition.
+ progress.value = .4f
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Transition(0.4f))
+
+ // Transition is at full progress.
+ progress.value = 1f
+ assertThat(transitionProgress).isEqualTo(CommunalTransitionProgressModel.Transition(1f))
+
+ // Transition finishes.
+ underTest.setTransitionState(
+ MutableStateFlow(ObservableTransitionState.Idle(CommunalScenes.Communal))
+ )
+ assertThat(transitionProgress)
+ .isEqualTo(CommunalTransitionProgressModel.Idle(CommunalScenes.Communal))
+ }
+
+ @Test
+ fun isIdleOnCommunal() =
+ testScope.runTest {
+ // isIdleOnCommunal is false when not on communal.
+ val isIdleOnCommunal by collectLastValue(underTest.isIdleOnCommunal)
+ assertThat(isIdleOnCommunal).isEqualTo(false)
+
+ val transitionState: MutableStateFlow<ObservableTransitionState> =
+ MutableStateFlow(ObservableTransitionState.Idle(CommunalScenes.Communal))
+
+ // Transition to communal.
+ repository.setTransitionState(transitionState)
+ assertThat(isIdleOnCommunal).isEqualTo(true)
+
+ // Start transition away from communal.
+ transitionState.value =
+ ObservableTransitionState.Transition(
+ fromScene = CommunalScenes.Communal,
+ toScene = CommunalScenes.Blank,
+ currentScene = flowOf(CommunalScenes.Blank),
+ progress = flowOf(0f),
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ assertThat(isIdleOnCommunal).isEqualTo(false)
+ }
+
+ @Test
+ fun isCommunalVisible() =
+ testScope.runTest {
+ // isCommunalVisible is false when not on communal.
+ val isCommunalVisible by collectLastValue(underTest.isCommunalVisible)
+ assertThat(isCommunalVisible).isEqualTo(false)
+
+ val transitionState: MutableStateFlow<ObservableTransitionState> =
+ MutableStateFlow(
+ ObservableTransitionState.Transition(
+ fromScene = CommunalScenes.Blank,
+ toScene = CommunalScenes.Communal,
+ currentScene = flowOf(CommunalScenes.Communal),
+ progress = flowOf(0f),
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ )
+
+ // Start transition to communal.
+ repository.setTransitionState(transitionState)
+ assertThat(isCommunalVisible).isEqualTo(true)
+
+ // Finish transition to communal
+ transitionState.value = ObservableTransitionState.Idle(CommunalScenes.Communal)
+ assertThat(isCommunalVisible).isEqualTo(true)
+
+ // Start transition away from communal.
+ transitionState.value =
+ ObservableTransitionState.Transition(
+ fromScene = CommunalScenes.Communal,
+ toScene = CommunalScenes.Blank,
+ currentScene = flowOf(CommunalScenes.Blank),
+ progress = flowOf(1.0f),
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ assertThat(isCommunalVisible).isEqualTo(true)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
index 6ca04df..84dbfd4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
@@ -39,6 +39,7 @@
import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.log.CommunalUiEvent
@@ -106,6 +107,7 @@
underTest =
CommunalEditModeViewModel(
+ kosmos.communalSceneInteractor,
kosmos.communalInteractor,
kosmos.communalSettingsInteractor,
mediaHost,
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 be44339..5e19a41 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
@@ -28,14 +28,15 @@
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
-import com.android.systemui.communal.data.repository.FakeCommunalRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
import com.android.systemui.communal.data.repository.fakeCommunalMediaRepository
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.fakeCommunalTutorialRepository
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalTutorialInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -106,7 +107,7 @@
private lateinit var userRepository: FakeUserRepository
private lateinit var shadeTestUtil: ShadeTestUtil
private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
- private lateinit var communalRepository: FakeCommunalRepository
+ private lateinit var communalRepository: FakeCommunalSceneRepository
private lateinit var underTest: CommunalViewModel
@@ -126,7 +127,7 @@
mediaRepository = kosmos.fakeCommunalMediaRepository
userRepository = kosmos.fakeUserRepository
shadeTestUtil = kosmos.shadeTestUtil
- communalRepository = kosmos.fakeCommunalRepository
+ communalRepository = kosmos.fakeCommunalSceneRepository
kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
@@ -143,6 +144,7 @@
context.resources,
kosmos.keyguardTransitionInteractor,
kosmos.keyguardInteractor,
+ kosmos.communalSceneInteractor,
kosmos.communalInteractor,
kosmos.communalTutorialInteractor,
kosmos.shadeInteractor,
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 b4f87c4..420b11c 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 @@
verify(activityStarter)
.startPendingIntentMaybeDismissingKeyguard(
eq(testIntent),
+ eq(false),
isNull(),
notNull(),
refEq(fillInIntent),
@@ -91,6 +92,7 @@
verify(activityStarter)
.startPendingIntentMaybeDismissingKeyguard(
eq(testIntent),
+ eq(false),
isNull(),
isNull(),
refEq(fillInIntent),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index eef2337..a3a4952 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -45,8 +45,8 @@
import com.android.systemui.ambient.touch.scrim.ScrimManager
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
-import com.android.systemui.communal.data.repository.FakeCommunalRepository
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
@@ -79,7 +79,6 @@
import org.mockito.Mockito
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.isNull
-import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -156,7 +155,7 @@
@Mock lateinit var mDreamOverlayCallbackController: DreamOverlayCallbackController
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
- private lateinit var communalRepository: FakeCommunalRepository
+ private lateinit var communalRepository: FakeCommunalSceneRepository
@Captor var mViewCaptor: ArgumentCaptor<View>? = null
private lateinit var mService: DreamOverlayService
@@ -167,7 +166,7 @@
lifecycleRegistry = FakeLifecycleRegistry(mLifecycleOwner)
bouncerRepository = kosmos.fakeKeyguardBouncerRepository
- communalRepository = kosmos.fakeCommunalRepository
+ communalRepository = kosmos.fakeCommunalSceneRepository
whenever(mDreamOverlayComponent.getDreamOverlayContainerViewController())
.thenReturn(mDreamOverlayContainerViewController)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 20ffa33..33e2cac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -26,7 +26,7 @@
import com.android.systemui.Flags as AConfigFlags
import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.data.repository.communalRepository
+import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
@@ -71,7 +71,7 @@
private val testScope = kosmos.testScope
private val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
private val keyguardRepository by lazy { kosmos.fakeKeyguardRepository }
- private val communalRepository by lazy { kosmos.communalRepository }
+ private val communalRepository by lazy { kosmos.communalSceneRepository }
private val screenOffAnimationController by lazy { kosmos.screenOffAnimationController }
private val deviceEntryRepository by lazy { kosmos.fakeDeviceEntryRepository }
private val notificationsKeyguardInteractor by lazy { kosmos.notificationsKeyguardInteractor }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
index f1cd0c8..79e4fef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
@@ -179,6 +179,7 @@
val label = context.getString(R.string.status_bar_alarm)
return QSTileState(
{ Icon.Loaded(context.getDrawable(R.drawable.ic_alarm)!!, null) },
+ R.drawable.ic_alarm,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt
index 6e9db2c..a0d26c2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt
@@ -254,6 +254,7 @@
val label = context.getString(R.string.battery_detail_switch_title)
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt
index d05e98f..ea7b7c5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt
@@ -78,6 +78,7 @@
val label = context.getString(R.string.quick_settings_color_correction_label)
return QSTileState(
{ Icon.Loaded(context.getDrawable(R.drawable.ic_qs_color_correction)!!, null) },
+ R.drawable.ic_qs_color_correction,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt
index 3972938..b4ff565 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt
@@ -245,6 +245,7 @@
): QSTileState {
return QSTileState(
{ icon?.let { com.android.systemui.common.shared.model.Icon.Loaded(icon, null) } },
+ null,
"test label",
activationState,
"test subtitle",
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt
index b7b3fdb..f8e01be 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt
@@ -66,6 +66,7 @@
null
)
},
+ R.drawable.ic_qs_font_scaling,
context.getString(R.string.quick_settings_font_scaling_label),
QSTileState.ActivationState.ACTIVE,
null,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
index 39755bf..c44836a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
@@ -70,6 +70,7 @@
QSTileState.ActivationState.ACTIVE,
context.getString(R.string.quick_settings_networks_available),
Icon.Loaded(context.getDrawable(wifiRes)!!, contentDescription = null),
+ wifiRes,
context.getString(R.string.quick_settings_internet_label)
)
QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
@@ -96,6 +97,7 @@
context.getDrawable(R.drawable.ic_qs_no_internet_unavailable)!!,
contentDescription = null
),
+ R.drawable.ic_qs_no_internet_unavailable,
context.getString(R.string.quick_settings_networks_unavailable)
)
QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
@@ -105,11 +107,13 @@
activationState: QSTileState.ActivationState,
secondaryLabel: String,
icon: Icon,
+ iconRes: Int,
contentDescription: String,
): QSTileState {
val label = context.getString(R.string.quick_settings_internet_label)
return QSTileState(
{ icon },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt
index ccd7ed9..a7bd697 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt
@@ -39,9 +39,7 @@
private val colorInversionTileConfig = kosmos.qsColorInversionTileConfig
private val subtitleArrayId =
SubtitleArrayMapping.getSubtitleId(colorInversionTileConfig.tileSpec.spec)
- private val subtitleArray by lazy {
- context.resources.getStringArray(subtitleArrayId)
- }
+ private val subtitleArray by lazy { context.resources.getStringArray(subtitleArrayId) }
// Using lazy (versus =) to make sure we override the right context -- see b/311612168
private val mapper by lazy {
ColorInversionTileMapper(
@@ -93,6 +91,7 @@
val label = context.getString(R.string.quick_settings_inversion_label)
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt
index 5d2e701..75273f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt
@@ -281,21 +281,16 @@
secondaryLabel: String?
): QSTileState {
val label = context.getString(R.string.quick_settings_night_display_label)
-
+ val iconRes =
+ if (activationState == QSTileState.ActivationState.ACTIVE)
+ R.drawable.qs_nightlight_icon_on
+ else R.drawable.qs_nightlight_icon_off
val contentDescription =
if (TextUtils.isEmpty(secondaryLabel)) label
else TextUtils.concat(label, ", ", secondaryLabel)
return QSTileState(
- {
- Icon.Loaded(
- context.getDrawable(
- if (activationState == QSTileState.ActivationState.ACTIVE)
- R.drawable.qs_nightlight_icon_on
- else R.drawable.qs_nightlight_icon_off
- )!!,
- null
- )
- },
+ { Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt
index 7ef020d..3189a9e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt
@@ -97,6 +97,7 @@
val label = context.getString(R.string.quick_settings_onehanded_label)
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt
index d26a213..08e5cbe 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt
@@ -100,6 +100,7 @@
null
)
},
+ com.android.systemui.res.R.drawable.ic_qr_code_scanner,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt
index 10e9bd6..ca30e9c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt
@@ -83,17 +83,13 @@
): QSTileState {
val label =
context.getString(com.android.internal.R.string.reduce_bright_colors_feature_name)
+ val iconRes =
+ if (activationState == QSTileState.ActivationState.ACTIVE)
+ R.drawable.qs_extra_dim_icon_on
+ else R.drawable.qs_extra_dim_icon_off
return QSTileState(
- {
- Icon.Loaded(
- context.getDrawable(
- if (activationState == QSTileState.ActivationState.ACTIVE)
- R.drawable.qs_extra_dim_icon_on
- else R.drawable.qs_extra_dim_icon_off
- )!!,
- null
- )
- },
+ { Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
context.resources
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
index 60c69f4..04ca38f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
@@ -172,6 +172,7 @@
val label = context.getString(R.string.quick_settings_rotation_unlocked_label)
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt
index d162c77..9bb6141 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt
@@ -92,6 +92,7 @@
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt
index 31ae9c5..336b566 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt
@@ -111,6 +111,7 @@
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt
index 5e7aadc..b08f39b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt
@@ -147,6 +147,7 @@
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt
index a977606..c021caa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt
@@ -70,6 +70,7 @@
): QSTileState {
return QSTileState(
{ Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes,
label,
activationState,
secondaryLabel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
index afe7b8f..7388d51 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
@@ -54,9 +54,11 @@
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
@SmallTest
@@ -162,16 +164,25 @@
with(qsImpl!!) {
verify(this).setQsVisible(false)
- verify(this)
+ verify(this, never())
.setQsExpansion(
- /* expansion= */ 0f,
- /* panelExpansionFraction= */ 1f,
- /* proposedTranslation= */ 0f,
- /* squishinessFraction= */ 1f,
+ /* expansion= */ anyFloat(),
+ /* panelExpansionFraction= */ anyFloat(),
+ /* proposedTranslation= */ anyFloat(),
+ /* squishinessFraction= */ anyFloat(),
)
verify(this).setListening(false)
verify(this).setExpanded(false)
}
+
+ underTest.applyLatestExpansionAndSquishiness()
+ verify(qsImpl!!)
+ .setQsExpansion(
+ /* expansion= */ 0f,
+ /* panelExpansionFraction= */ 1f,
+ /* proposedTranslation= */ 0f,
+ /* squishinessFraction= */ 1f,
+ )
}
@Test
@@ -186,16 +197,25 @@
underTest.setState(QSSceneAdapter.State.QQS)
with(qsImpl!!) {
verify(this).setQsVisible(true)
- verify(this)
+ verify(this, never())
.setQsExpansion(
- /* expansion= */ 0f,
- /* panelExpansionFraction= */ 1f,
- /* proposedTranslation= */ 0f,
- /* squishinessFraction= */ 1f,
+ /* expansion= */ anyFloat(),
+ /* panelExpansionFraction= */ anyFloat(),
+ /* proposedTranslation= */ anyFloat(),
+ /* squishinessFraction= */ anyFloat(),
)
verify(this).setListening(true)
verify(this).setExpanded(false)
}
+
+ underTest.applyLatestExpansionAndSquishiness()
+ verify(qsImpl!!)
+ .setQsExpansion(
+ /* expansion= */ 0f,
+ /* panelExpansionFraction= */ 1f,
+ /* proposedTranslation= */ 0f,
+ /* squishinessFraction= */ 1f,
+ )
}
@Test
@@ -210,16 +230,25 @@
underTest.setState(QSSceneAdapter.State.QS)
with(qsImpl!!) {
verify(this).setQsVisible(true)
- verify(this)
+ verify(this, never())
.setQsExpansion(
- /* expansion= */ 1f,
- /* panelExpansionFraction= */ 1f,
- /* proposedTranslation= */ 0f,
- /* squishinessFraction= */ 1f,
+ /* expansion= */ anyFloat(),
+ /* panelExpansionFraction= */ anyFloat(),
+ /* proposedTranslation= */ anyFloat(),
+ /* squishinessFraction= */ anyFloat(),
)
verify(this).setListening(true)
verify(this).setExpanded(true)
}
+
+ underTest.applyLatestExpansionAndSquishiness()
+ verify(qsImpl!!)
+ .setQsExpansion(
+ /* expansion= */ 1f,
+ /* panelExpansionFraction= */ 1f,
+ /* proposedTranslation= */ 0f,
+ /* squishinessFraction= */ 1f,
+ )
}
@Test
@@ -235,16 +264,25 @@
underTest.setState(QSSceneAdapter.State.Expanding(progress))
with(qsImpl!!) {
verify(this).setQsVisible(true)
- verify(this)
+ verify(this, never())
.setQsExpansion(
- /* expansion= */ progress,
- /* panelExpansionFraction= */ 1f,
- /* proposedTranslation= */ 0f,
- /* squishinessFraction= */ 1f,
+ /* expansion= */ anyFloat(),
+ /* panelExpansionFraction= */ anyFloat(),
+ /* proposedTranslation= */ anyFloat(),
+ /* squishinessFraction= */ anyFloat(),
)
verify(this).setListening(true)
verify(this).setExpanded(true)
}
+
+ underTest.applyLatestExpansionAndSquishiness()
+ verify(qsImpl!!)
+ .setQsExpansion(
+ /* expansion= */ progress,
+ /* panelExpansionFraction= */ 1f,
+ /* proposedTranslation= */ 0f,
+ /* squishinessFraction= */ 1f,
+ )
}
@Test
@@ -260,16 +298,25 @@
underTest.setState(QSSceneAdapter.State.UnsquishingQQS { squishiness })
with(qsImpl!!) {
verify(this).setQsVisible(true)
- verify(this)
+ verify(this, never())
.setQsExpansion(
- /* expansion= */ 0f,
- /* panelExpansionFraction= */ 1f,
- /* proposedTranslation= */ 0f,
- /* squishinessFraction= */ squishiness,
+ /* expansion= */ anyFloat(),
+ /* panelExpansionFraction= */ anyFloat(),
+ /* proposedTranslation= */ anyFloat(),
+ /* squishinessFraction= */ anyFloat(),
)
verify(this).setListening(true)
verify(this).setExpanded(false)
}
+
+ underTest.applyLatestExpansionAndSquishiness()
+ verify(qsImpl!!)
+ .setQsExpansion(
+ /* expansion= */ 0f,
+ /* panelExpansionFraction= */ 1f,
+ /* proposedTranslation= */ 0f,
+ /* squishinessFraction= */ squishiness,
+ )
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
index 8cb811d..a67a8ab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
@@ -78,7 +78,7 @@
}
@Test
- @EnableFlags(Flags.FLAG_MEDIA_CONTROLS_USER_INITIATED_DISMISS)
+ @EnableFlags(Flags.FLAG_MEDIA_CONTROLS_USER_INITIATED_DELETEINTENT)
fun mediaDataRemoved_userInitiated_dismissNotif() {
val notifEntryCaptor = argumentCaptor<NotificationEntry>()
val notifEntry = mock<NotificationEntry>()
@@ -93,7 +93,7 @@
}
@Test
- @EnableFlags(Flags.FLAG_MEDIA_CONTROLS_USER_INITIATED_DISMISS)
+ @EnableFlags(Flags.FLAG_MEDIA_CONTROLS_USER_INITIATED_DELETEINTENT)
fun mediaDataRemoved_notUserInitiated_doesNotDismissNotif() {
listenerCaptor.lastValue.onMediaDataRemoved(KEY, false)
@@ -101,7 +101,7 @@
}
@Test
- @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_USER_INITIATED_DISMISS)
+ @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_USER_INITIATED_DELETEINTENT)
fun mediaDataRemoved_notUserInitiated_flagOff_dismissNotif() {
val notifEntryCaptor = argumentCaptor<NotificationEntry>()
val notifEntry = mock<NotificationEntry>()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
index 288c083..db5921d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
@@ -118,8 +118,6 @@
underTest.setGroupExpanded(summary1, false)
// Expanding again should throw.
- // TODO(b/320238410): Remove this check when robolectric supports wtf assertions.
- Assume.assumeFalse(Build.FINGERPRINT.contains("robolectric"))
assertLogsWtf { underTest.setGroupExpanded(summary1, true) }
}
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 0ca6207..57d3251 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
@@ -33,6 +33,7 @@
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.animation.LaunchableView
import com.android.systemui.assist.AssistManager
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
@@ -94,6 +95,7 @@
@Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityIntentHelper: ActivityIntentHelper
+ @Mock private lateinit var communalSceneInteractor: CommunalSceneInteractor
private lateinit var underTest: LegacyActivityStarterInternalImpl
private val mainExecutor = FakeExecutor(FakeSystemClock())
private val shadeAnimationInteractor =
@@ -127,6 +129,7 @@
userTracker = userTracker,
activityIntentHelper = activityIntentHelper,
mainExecutor = mainExecutor,
+ communalSceneInteractor = communalSceneInteractor,
)
whenever(userTracker.userHandle).thenReturn(UserHandle.OWNER)
}
@@ -138,7 +141,7 @@
whenever(keyguardStateController.isShowing).thenReturn(true)
whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
- underTest.startPendingIntentDismissingKeyguard(pendingIntent)
+ underTest.startPendingIntentDismissingKeyguard(intent = pendingIntent, dismissShade = true)
mainExecutor.runAllReady()
verify(statusBarKeyguardViewManager)
@@ -232,6 +235,7 @@
underTest.startPendingIntentDismissingKeyguard(
intent = pendingIntent,
+ dismissShade = true,
intentSentUiThreadCallback = null,
associatedView = associatedView,
)
@@ -344,6 +348,7 @@
) {
underTest.startPendingIntentDismissingKeyguard(
intent = intent,
+ dismissShade = true,
intentSentUiThreadCallback = intentSentUiThreadCallback,
animationController = animationController,
showOverLockscreen = true,
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 072ec99..de65931 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -70,9 +70,11 @@
/**
* Similar to {@link #startPendingIntentMaybeDismissingKeyguard(PendingIntent, Runnable,
* ActivityTransitionAnimator.Controller)}, but also specifies a fill-in intent and extra
- * options that could be used to populate the pending intent and launch the activity.
+ * option that could be used to populate the pending intent and launch the activity. This also
+ * allows the caller to avoid dismissing the shade.
*/
void startPendingIntentMaybeDismissingKeyguard(PendingIntent intent,
+ boolean dismissShade,
@Nullable Runnable intentSentUiThreadCallback,
@Nullable ActivityTransitionAnimator.Controller animationController,
@Nullable Intent fillInIntent,
diff --git a/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_background.xml b/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_background.xml
index 6e6e032..c83b6d3 100644
--- a/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_background.xml
+++ b/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_background.xml
@@ -30,8 +30,8 @@
android:end="20dp"
android:gravity="end|center_vertical">
<vector
- android:width="@dimen/screenrecord_spinner_arrow_size"
- android:height="@dimen/screenrecord_spinner_arrow_size"
+ android:width="@dimen/hearing_devices_preset_spinner_arrow_size"
+ android:height="@dimen/hearing_devices_preset_spinner_arrow_size"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?androidprv:attr/colorControlNormal">
diff --git a/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml b/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml
new file mode 100644
index 0000000..1d9307b
--- /dev/null
+++ b/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml
@@ -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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/hearing_devices_preset_option_text"
+ style="?android:attr/spinnerDropDownItemStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/hearing_devices_preset_spinner_height"
+ android:paddingStart="@dimen/hearing_devices_preset_spinner_text_padding_start"
+ android:gravity="center_vertical"
+ android:ellipsize="end" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml b/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml
new file mode 100644
index 0000000..77172ca
--- /dev/null
+++ b/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml
@@ -0,0 +1,46 @@
+<!--
+ 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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/hearing_devices_preset_spinner_height"
+ android:paddingStart="@dimen/hearing_devices_preset_spinner_text_padding_start"
+ android:paddingTop="@dimen/hearing_devices_preset_spinner_text_padding_vertical"
+ android:paddingBottom="@dimen/hearing_devices_preset_spinner_text_padding_vertical"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:textAppearance="@style/TextAppearance.Dialog.Title"
+ android:lineSpacingExtra="6dp"
+ android:text="@string/hearing_devices_preset_label"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textSize="14sp"
+ android:gravity="center_vertical"
+ android:layout_weight="1" />
+ <TextView
+ android:id="@+id/hearing_devices_preset_option_text"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:textAppearance="@style/TextAppearance.Dialog.Body"
+ android:lineSpacingExtra="6dp"
+ android:gravity="center_vertical"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:layout_weight="1" />
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
index 8e1d0a5..2bf6f80 100644
--- a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
+++ b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
@@ -17,7 +17,6 @@
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/root"
style="@style/Widget.SliceView.Panel"
android:layout_width="wrap_content"
@@ -36,16 +35,22 @@
android:id="@+id/preset_spinner"
style="@style/BluetoothTileDialog.Device"
android:layout_width="match_parent"
- android:layout_height="@dimen/hearing_devices_preset_spinner_height"
- android:layout_marginTop="@dimen/hearing_devices_preset_spinner_margin"
- android:layout_marginBottom="@dimen/hearing_devices_preset_spinner_margin"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/hearing_devices_preset_spinner_height"
+ android:layout_marginTop="@dimen/hearing_devices_layout_margin"
+ android:layout_marginBottom="@dimen/hearing_devices_layout_margin"
android:gravity="center_vertical"
android:background="@drawable/hearing_devices_preset_spinner_background"
android:popupBackground="@drawable/hearing_devices_preset_spinner_popup_background"
+ android:dropDownVerticalOffset="@dimen/hearing_devices_preset_spinner_height"
+ android:dropDownWidth="match_parent"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/device_list"
app:layout_constraintBottom_toTopOf="@id/pair_new_device_button"
+ android:longClickable="false"
android:visibility="gone"/>
<androidx.constraintlayout.widget.Barrier
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index abbb4cb..e19b3fe 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"het \'n prent gestuur"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Stoor tans skermkiekie..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Stoor tans skermskoot in werkprofiel …"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Skermkiekie is gestoor"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Kon nie skermkiekie stoor nie"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Eksterne skerm"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Bind nuwe toestel saam"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nuwe toestel saam te bind"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kon nie voorafstelling opdateer nie"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokkeer toestelmikrofoon?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokkeer toestelkamera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokkeer toestelkamera en mikrofoon?"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 3bdf212..b257f0f 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ምስል ተልኳል"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ቅጽበታዊ ገፅ ዕይታ በማስቀመጥ ላይ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ቅጽበታዊ ገፅ እይታን ወደ የስራ መገለጫ በማስቀመጥ ላይ…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"ቅጽበታዊ ገፅ ዕይታ ተቀምጧል"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ቅጽበታዊ ገፅ ዕይታን ማስቀመጥ አልተቻለም"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ውጫዊ ማሳያ"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index ac210e2..d145ee9 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"أرسَل صورة"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"جارٍ حفظ لقطة الشاشة..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"جارٍ حفظ لقطة الشاشة في ملف العمل…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"تم حفظ لقطة الشاشة."</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"تعذّر حفظ لقطة الشاشة"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"الشاشة الخارجية"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 45363dd..33c0b7e 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"স্ক্ৰীনশ্বট ছেভ কৰি থকা হৈছে…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"কৰ্মস্থানৰ প্ৰ’ফাইলত স্ক্ৰীনশ্বট ছেভ কৰি থকা হৈছে…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"স্ক্ৰীনশ্বট ছেভ কৰা হ’ল"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"স্ক্ৰীনশ্বট ছেভ কৰিব পৰা নগ\'ল"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"বাহ্যিক ডিছপ্লে’"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e796364..29fb86e 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"şəkil göndərdi"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Skrinşot yadda saxlanır..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"İş profili skrinşotu saxlanılır…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Skrinşot şəxsidə saxlanılır"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Skrinşot yadda saxlandı"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Skrinşotu yadda saxlamaq alınmadı"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Xarici displey"</string>
@@ -271,7 +272,7 @@
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toxunaraq cihaza qoşulun, yaxud əlaqəni ayırın"</string>
<string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Yeni cihaz birləşdirin"</string>
<string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Hamısına baxın"</string>
- <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth aç"</string>
+ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-u açın"</string>
<string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Qoşulub"</string>
<string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Audio paylaşma"</string>
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Yadda saxlandı"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Yeni cihaz birləşdirin"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz birləşdirmək üçün klikləyin"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncəllənmədi"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonu blokdan çıxarılsın?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerası blokdan çıxarılsın?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası və mikrofonu blokdan çıxarılsın?"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 23a09cad..5ff6b1a 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslao/la sliku"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Čuvanje snimka ekrana..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Snimak ekrana se čuva na poslovnom profilu…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Snimak ekrana je sačuvan"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Čuvanje snimka ekrana nije uspelo"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Spoljni ekran"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Upari novi uređaj"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili nov uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite da odblokirate kameru i mikrofon uređaja?"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 7dc9480..aa34a88 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"адпраўлены відарыс"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Захаванне скрыншота..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Захаванне здымка экрана ў працоўны профіль…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Здымак экрана захаваны"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Не атрымалася зрабіць здымак экрана"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Знешні дысплэй"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
@@ -710,7 +714,7 @@
<string name="notification_more_settings" msgid="4936228656989201793">"Дадатковыя налады"</string>
<string name="notification_app_settings" msgid="8963648463858039377">"Наладзіць"</string>
<string name="notification_conversation_bubble" msgid="2242180995373949022">"Паказаць усплывальнае апавяшчэнне"</string>
- <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Выдаліць усплывальныя апавяшчэнні"</string>
+ <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Выдаліць усплывальныя чаты"</string>
<string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
<string name="notification_menu_gear_description" msgid="6429668976593634862">"кіраванне апавяшчэннямі"</string>
<string name="notification_menu_snooze_description" msgid="4740133348901973244">"параметры адкладвання апавяшчэнняў"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 42265b0..4b305ae9 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"изпратено изображение"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Екранната снимка се запазва..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Екранната снимка се запазва в служебния профил…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Екранната снимка е запазена"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Не можа да се запази екранна снимка"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Външен екран"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 3d008cb..87d5ffe 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"একটি ছবি পাঠানো হয়েছে"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"স্ক্রিনশট সেভ করা হচ্ছে..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"অফিস প্রোফাইলে স্ক্রিনশট সেভ করা হচ্ছে…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"স্ক্রিনশট সেভ করা হয়েছে"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"স্ক্রিনশট সেভ করা যায়নি"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"এক্সটার্নাল ডিসপ্লে"</string>
@@ -277,7 +279,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"সেভ করা আছে"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ডিসকানেক্ট করুন"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"চালু করুন"</string>
- <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"আগামীকাল অটোমেটিক আবার চালু হবে"</string>
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"আগামীকাল আবার অটোমেটিক চালু হবে"</string>
<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>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"অডিও শেয়ারিং"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 96b83c1..2b80eef 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslao/la sliku"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Spašavanje snimka ekrana..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pohranjivanje snimka ekrana na radni profil…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Snimak ekrana je sačuvan"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Nije moguće sačuvati snimak ekrana"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Vanjski ekran"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Uparite novi uređaj"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da uparite novi uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadane postavke nije uspjelo"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokirati mikrofon uređaja?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokirati kameru uređaja?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokirati kameru i mikrofon uređaja?"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index cf9717f..66875ca 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ha enviat una imatge"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"S\'està desant la captura de pantalla..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"S\'està desant la captura al perfil de treball…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"S\'ha desat la captura de pantalla"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"No s\'ha pogut desar la captura de pantalla"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Pantalla externa"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Vincula un dispositiu nou"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fes clic per vincular un dispositiu nou"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vols desbloquejar la càmera i el micròfon del dispositiu?"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index a5a88d4..706076c 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"odesílá obrázek"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Ukládání snímku obrazovky..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ukládání snímku obrazovky do pracovního profilu…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Snímek obrazovky byl uložen"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Snímek obrazovky se nepodařilo uložit"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Externí displej"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Spárovat nové zařízení"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zařízení"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Předvolbu nelze aktualizovat"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokovat mikrofon zařízení?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokovat fotoaparát zařízení?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokovat fotoaparát a mikrofon zařízení?"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 55a5de9..836fe26 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sendte et billede"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Gemmer screenshot..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Gemmer screenshot på din arbejdsprofil…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Gemmer screenshottet på din private profil"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshottet blev gemt"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Screenshottet kunne ikke gemmes"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ekstern skærm"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Par ny enhed"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik for at parre en ny enhed"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Forindstillingen kunne ikke opdateres"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du fjerne blokeringen af enhedens mikrofon?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du fjerne blokeringen af enhedens kamera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du fjerne blokeringen af enhedens kamera og mikrofon?"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 1f0550f..8c36447 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"Bild gesendet"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Screenshot wird gespeichert..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Screenshot wird in Arbeitsprofil gespeichert…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot gespeichert"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Screenshot konnte nicht gespeichert werden"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Äußeres Display"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Neues Gerät koppeln"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicken, um neues Gerät zu koppeln"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Voreinstellung konnte nicht aktualisiert werden"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Blockierung des Gerätemikrofons aufheben?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Blockierung der Gerätekamera aufheben?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blockierung von Gerätekamera und Gerätemikrofon aufheben?"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 937ba70..11c3481 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"έστειλε μια εικόνα"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Αποθήκευση στιγμιότυπου οθόνης..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Αποθήκευση στιγμιότ. οθόνης στο προφίλ εργασίας…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Το στιγμιότυπο οθόνης αποθηκεύτηκε"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Μη δυνατή αποθήκευση του στιγμιότυπου οθόνης"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Εξωτερική οθόνη"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 137b243..542d660 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Saving screenshot to private"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot saved"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Couldn\'t save screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"External display"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Pair new device"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 1f68f46..6df88b9 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Saving screenshot to private"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot saved"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Couldn\'t save screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"External Display"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Pair new device"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 137b243..542d660 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Saving screenshot to private"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot saved"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Couldn\'t save screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"External display"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Pair new device"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 137b243..542d660 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Saving screenshot to private"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot saved"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Couldn\'t save screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"External display"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Pair new device"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index eb705ae..8354cc7 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Saving screenshot to private"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot saved"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Couldn\'t save screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"External Display"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Pair new device"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index ea7748c..32c242d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"envió una imagen"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Guardando la captura de pantalla..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Guardando cap. de pantalla en perfil de trabajo…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Se guardó la captura de pantalla"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"No se pudo guardar la captura de pantalla"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Pantalla externa"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Vincular dispositivo nuevo"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para vincular un dispositivo nuevo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No se pudo actualizar el ajuste predeterminado"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Quieres desbloquear el micrófono del dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Quieres desbloquear la cámara del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Quieres desbloquear la cámara y el micrófono del dispositivo?"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8365067..9a5f70a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ha enviado una imagen"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Guardando captura..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Guardando captura en el perfil de trabajo…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Se ha guardado la captura de pantalla"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"No se ha podido guardar la captura de pantalla"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Pantalla externa"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Emparejar nuevo dispositivo"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para emparejar un nuevo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No se ha podido actualizar el preajuste"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Desbloquear el micrófono del dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Desbloquear la cámara del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Desbloquear la cámara y el micrófono del dispositivo?"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 2df5681..3d15aab 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"saatis kujutise"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Kuvatõmmise salvestamine ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ekraanipildi salvestamine tööprofiilile …"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Ekraanipildi salvestamine privaatseks"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Ekraanipilt salvestati"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Ekraanipilti ei õnnestunud salvestada"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Väline ekraan"</string>
@@ -278,7 +279,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkesta ühendus"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveeri"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Lülita automaatselt homme uuesti sisse"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktsioonid, nagu Kiirjagamine ja Leia mu seade, kasutavad Bluetoothi"</string>
+ <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>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"Heli jagamine"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="8626191139359072540">"Heli jagamine"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Uue seadme sidumine"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Uue seadme sidumiseks klõpsake"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kas tühistada seadme kaamera ja mikrofoni blokeerimine?"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 1f10821..db0e8e9 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"erabiltzaileak irudi bat bidali du"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Pantaila-argazkia gordetzen…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pantaila-argazkia laneko profilean gordetzen…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Pantaila-argazkia profil pribatuan gordetzen"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Gorde da pantaila-argazkia"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Ezin izan da gorde pantaila-argazkia"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Kanpoko pantaila"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Parekatu beste gailu bat"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Egin klik beste gailu bat parekatzeko"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ezin izan da eguneratu aurrezarpena"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Gailuaren mikrofonoa desblokeatu nahi duzu?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Gailuaren kamera desblokeatu nahi duzu?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Gailuaren kamera eta mikrofonoa desblokeatu nahi dituzu?"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 94befe4..f2372a6 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"تصویری ارسال کرد"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"درحال ذخیره نماگرفت…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"درحال ذخیره کردن نماگرفت در نمایه کاری…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"درحال ذخیره کردن نماگرفت در نمایه خصوصی"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"نماگرفت ذخیره شد"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"نماگرفت ذخیره نشد"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"نمایشگر خارجی"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 08c7adb..9172a9a 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"lähetti kuvan"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Tallennetaan kuvakaappausta..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Kuvakaappausta tallennetaan työprofiiliin…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Tallennetaan kuvakaappausta yksityiseen profiiliin"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Kuvakaappaus tallennettu"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Kuvakaappauksen tallennus epäonnistui"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ulkoinen näyttö"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Muodosta uusi laitepari"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Muodosta uusi laitepari klikkaamalla"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 59b9e42..2697eb3 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a envoyé une image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Enregistrement capture écran…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sauv. de la capture dans le profil prof. en cours…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Capture d\'écran enregistrée"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Impossible d\'enregistrer la capture d\'écran"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Écran externe"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Associer un nouvel appareil"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquez ici pour associer un nouvel appareil"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour le préréglage"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le microphone?"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 79f70af..945d353 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a envoyé une image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Enregistrement de la capture d\'écran…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Enregistrement de capture d\'écran dans profil pro…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Capture d\'écran enregistrée"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Impossible d\'enregistrer la capture d\'écran"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Écran externe"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Associer un nouvel appareil"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquer pour associer un nouvel appareil"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index fe2f112..913d65f 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -36,7 +36,7 @@
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Xirar pantalla automaticamente"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Queres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Queres permitir que a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda ao dispositivo (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?\nEsta aplicación non está autorizada para realizar gravacións, pero podería capturar audio a través deste dispositivo USB."</string>
- <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Queres permitir que a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para usar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esta aplicación non está autorizada a realizar gravacións, pero podería capturar audio a través deste dispositivo USB. Ao usar a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> con este dispositivo, é posible que non se escoiten chamadas, notificacións nin alarmas."</string>
<string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ao usar a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> con este dispositivo, é posible que non se escoiten chamadas, notificacións nin alarmas."</string>
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou unha imaxe"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Gardando captura de pantalla…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Gardando captura de pantalla no perfil de traballo"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Gardouse a captura de pantalla"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Non se puido gardar a captura de pantalla"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Pantalla externa"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Vincular dispositivo novo"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic para vincular un novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Non se puido actualizar a configuración predeterminada"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Queres desbloquear o micrófono do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Queres desbloquear a cámara do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Queres desbloquear a cámara e o micrófono do dispositivo?"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 299598f..b6b2730 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"છબી મોકલી"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"સ્ક્રીનશોટ સાચવી રહ્યું છે…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ઑફિસની પ્રોફાઇલમાં સ્ક્રીનશૉટ સાચવી રહ્યાં છીએ…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"સ્ક્રીનશૉટ સાચવ્યો"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"સ્ક્રીનશૉટ સાચવી શક્યાં નથી"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"બાહ્ય ડિસ્પ્લે"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 4c34814..639a307 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"एक इमेज भेजी गई"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रीनशॉट सहेजा जा रहा है..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"स्क्रीनशॉट, वर्क प्रोफ़ाइल में सेव किया जा रहा है…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"स्क्रीनशॉट सेव किया गया"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"स्क्रीनशॉट सेव नहीं किया जा सका"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"बाहरी डिसप्ले"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 5b5bddc..6a53ad1 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"šalje sliku"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Spremanje snimke zaslona..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Spremanje snimke zaslona na poslovni profil…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Snimka zaslona je spremljena"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Snimka zaslona nije spremljena"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Vanjski prikaz"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Uparite novi uređaj"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili novi uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje unaprijed definiranih postavki nije uspjelo"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite li deblokirati mikrofon uređaja?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite li deblokirati kameru uređaja?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite li deblokirati kameru i mikrofon uređaja?"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index a2cf7b2..d0b87da 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"képet küldött"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Képernyőkép mentése..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Képernyőkép mentése a munkaprofilba…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"A képernyőkép mentése sikerült"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Nem sikerült a képernyőkép mentése"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Külső kijelző"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Új eszköz párosítása"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kattintson új eszköz párosításához"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Feloldja az eszköz kamerájának és mikrofonjának letiltását?"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index b0f4848..66dd606 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"պատկեր է ուղարկվել"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Սքրինշոթը պահվում է..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Սքրինշոթը պահվում է աշխատանքային պրոֆիլում…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Սքրինշոթը պահվեց"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Չհաջողվեց պահել սքրինշոթը"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Արտաքին էկրան"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index a0795dc..a72cae7 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"mengirim gambar"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Menyimpan screenshot..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Menyimpan screenshot ke profil kerja …"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot disimpan"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Tidak dapat menyimpan screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Layar Eksternal"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sambungkan perangkat baru"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menyambungkan perangkat baru"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat memperbarui preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Berhenti memblokir mikrofon perangkat?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Berhenti memblokir kamera perangkat?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Berhenti memblokir kamera dan mikrofon perangkat?"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index f32f6a6..ee99882 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sendi mynd"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Vistar skjámynd…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Vistar skjámynd á vinnusnið…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Vistar skjámynd í lokað"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Skjámynd vistuð"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Ekki var hægt að vista skjámynd"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ytri skjár"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Para nýtt tæki"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Smelltu til að para nýtt tæki"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Opna fyrir myndavél og hljóðnema tækisins?"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 1988459..b42bd95 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"è stata inviata un\'immagine"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Salvataggio screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvataggio screenshot nel profilo di lavoro…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot salvato"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Impossibile salvare lo screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Display esterno"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Accoppia nuovo dispositivo"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic per accoppiare un nuovo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossibile aggiornare preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vuoi sbloccare il microfono del dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vuoi sbloccare la fotocamera del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vuoi sbloccare la fotocamera e il microfono del dispositivo?"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index d31a95d..d19e9a1 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"נשלחה תמונה"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"המערכת שומרת את צילום המסך..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"צילום המסך נשמר בפרופיל העבודה…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"צילום המסך נשמר"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"לא ניתן היה לשמור את צילום המסך"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"תצוגה במסך חיצוני"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index bff8487..f29dee0 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"画像を送信しました"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"スクリーンショットを保存しています..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"スクリーンショットを仕事用プロファイルに保存中…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"スクリーンショットを保存しました"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"スクリーンショット保存エラー"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"外側ディスプレイ"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 51ba080..e37c16b 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"გაიგზავნა სურათი"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ეკრანის სურათის შენახვა…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"მიმდინარეობს ეკრანის ანაბეჭდის შენახვა სამუშაო პროფილში…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"ეკრანის ანაბეჭდი შენახულია"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ეკრანის ანაბეჭდის შენახვა ვერ მოხერხდა"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"გარე ეკრანი"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 27c8512..2618198 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"сурет жіберілді"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Скриншотты сақтауда…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Скриншот жұмыс профиліне сақталып жатыр…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Скриншот сақталды"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Скриншот сақталмады"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Сыртқы дисплей"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index bd0bf98..88259f3 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"បានផ្ញើរូបភាព"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"កំពុងរក្សាទុករូបថតអេក្រង់..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"កំពុងរក្សាទុករូបថតអេក្រង់ទៅកម្រងព័ត៌មានការងារ…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"បានរក្សាទុករូបថតអេក្រង់"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"មិនអាចរក្សាទុករូបថតអេក្រង់បានទេ"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ផ្ទាំងអេក្រង់ខាងក្រៅ"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index bc7ab50..cd14d0e 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಉಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ಗೆ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಉಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಉಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ಬಾಹ್ಯ ಡಿಸ್ಪ್ಲೇ"</string>
@@ -279,7 +281,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"ನಾಳೆ ಪುನಃ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಮಾಡಿ"</string>
<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>
+ <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ಬ್ಲೂಟೂತ್ ನಾಳೆ ಬೆಳಗ್ಗೆ ಆನ್ ಆಗುತ್ತದೆ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="8626191139359072540">"ಆಡಿಯೋವನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 0e6f9bf..8d34d00 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"이미지 보냄"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"캡쳐화면 저장 중..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"직장 프로필에 스크린샷 저장 중…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"스크린샷을 비공개 프로필에 저장 중"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"스크린샷 저장됨"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"스크린샷을 저장할 수 없음"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"외부 디스플레이"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 383a8e1..975faf1 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"сүрөт жөнөттү"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Скриншот сакталууда..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Скриншот жумуш профилине сакталууда…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Скриншот жеке профилге сакталууда"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Скриншот сакталды"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Скриншот сакталган жок"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Тышкы экран"</string>
@@ -278,7 +279,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ажыратуу"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"иштетүү"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Эртең автоматтык түрдө кайра күйгүзүү"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Тез бөлүшүү жана Түзмөгүм кайда? сыяктуу функциялар Bluetooth\'ту колдонушат"</string>
+ <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth Тез бөлүшүү жана Түзмөгүм кайда? сыяктуу функцияларда колдонулат"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth эртең таңда күйөт"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"Чогуу угуу"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="8626191139359072540">"Чогуу угулууда"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index a136976..22a64f8 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ສົ່ງຮູບແລ້ວ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ກຳລັງບັນທຶກພາບໜ້າຈໍ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ກຳລັງບັນທຶກຮູບໜ້າຈໍໃສ່ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"ກຳລັງບັນທຶກຮູບໜ້າຈໍໄວ້ໃນໂປຣໄຟລ໌ສ່ວນຕົວ"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"ບັນທຶກຮູບໜ້າຈໍໄວ້ແລ້ວ"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ບໍ່ສາມາດບັນທຶກຮູບໜ້າຈໍໄດ້"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ຈໍສະແດງຜົນພາຍນອກ"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 96be8e2..0622dc5 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"išsiuntė vaizdą"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Išsaugoma ekrano kopija..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Išsaugoma ekrano kopija darbo profilyje…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Ekrano kopija išsaugota"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Ekrano kopijos išsaugoti nepavyko"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Išorinė pateiktis"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Susieti naują įrenginį"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Spustelėkite, kad susietumėte naują įrenginį"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Išankstinių nustatymų atnaujinti nepavyko"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Panaikinti įrenginio mikrofono blokavimą?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Panaikinti įrenginio fotoaparato blokavimą?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Panaikinti įrenginio fotoaparato ir mikrofono blokavimą?"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b8a5476..7b7ba80 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"nosūtīts attēls"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Notiek ekrānuzņēmuma saglabāšana..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Notiek ekrānuzņēmuma saglabāšana darba profilā…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Ekrānuzņēmums saglabāts"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Ekrānuzņēmumu neizdevās saglabāt."</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ārējais displejs"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Savienot pārī jaunu ierīci"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Noklikšķiniet, lai savienotu pārī jaunu ierīci"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nevarēja atjaunināt pirmsiestatījumu"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vai atbloķēt ierīces mikrofonu?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vai atbloķēt ierīces kameru un mikrofonu?"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 2e0edbe..b9571ce 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"испрати слика"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Сликата на екранот се зачувува..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Се зачувува слика од екранот на вашиот работен профил…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Сликата од екранот е зачувана"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Не може да се зачува слика од екранот"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Надворешен екран"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index ad7d723..18fc5b4 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -26,7 +26,7 @@
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"USB വഴി ചാർജ് ചെയ്യാനാകില്ല"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"ഉപകരണത്തിനൊപ്പം ലഭിച്ച ചാർജർ ഉപയോഗിക്കുക"</string>
- <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"ബാറ്ററി ലാഭിക്കൽ ഓണാക്കണോ?"</string>
+ <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"ബാറ്ററി സേവർ ഓണാക്കണോ?"</string>
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"ബാറ്ററി ലാഭിക്കലിനെ കുറിച്ച്"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ഓൺ ചെയ്യുക"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"ഓണാക്കുക"</string>
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ചിത്രം അയച്ചു"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കുന്നു..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കുന്നു…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"സ്ക്രീൻഷോട്ട് സംരക്ഷിച്ചു"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കാനായില്ല"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ബാഹ്യ ഡിസ്പ്ലേ"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
@@ -720,7 +724,7 @@
<string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> സമയത്തേക്ക് സ്നൂസ് ചെയ്തു"</string>
<string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# മണിക്കൂർ}=2{# മണിക്കൂർ}other{# മണിക്കൂർ}}"</string>
<string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# മിനിറ്റ്}other{# മിനിറ്റ്}}"</string>
- <string name="battery_detail_switch_title" msgid="6940976502957380405">"ബാറ്ററി ലാഭിക്കൽ"</string>
+ <string name="battery_detail_switch_title" msgid="6940976502957380405">"ബാറ്ററി സേവർ"</string>
<string name="keyboard_key_button_template" msgid="8005673627272051429">"ബട്ടൺ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="keyboard_key_home" msgid="3734400625170020657">"ഹോം"</string>
<string name="keyboard_key_back" msgid="4185420465469481999">"ബാക്ക്"</string>
@@ -943,7 +947,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>
@@ -1017,7 +1021,7 @@
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"എഡ്ജിലേക്ക് നീക്കി മറയ്ക്കുക"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"എഡ്ജിൽ നിന്ന് നീക്കി കാണിക്കൂ"</string>
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"നീക്കം ചെയ്യുക"</string>
- <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"മാറ്റുക"</string>
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ടോഗിൾ ചെയ്യുക"</string>
<string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"എഡിറ്റ് ചെയ്യുക"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"ഉപകരണ നിയന്ത്രണങ്ങൾ"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"നിയന്ത്രണങ്ങൾ ചേർക്കാൻ ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index fb3531f..2a0b70a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"зураг илгээсэн"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Дэлгэцийн агшинг хадгалж байна…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Дэлгэцийн агшныг ажлын профайлд хадгалж байна…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Дэлгэцийн агшныг хаалттай профайлд хадгалж байна"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Дэлгэцээс дарсан зургийг хадгалсан"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Дэлгэцээс дарсан зургийг хадгалж чадсангүй"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Гадаад дэлгэц"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 249e7ac..57e58fa 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"इमेज पाठवली आहे"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रीनशॉट सेव्ह करत आहे…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"कार्य प्रोफाइलवर स्क्रीनशॉट सेव्ह करत आहे…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"स्क्रीनशॉट सेव्ह केला"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"स्क्रीनशॉट सेव्ह करू शकलो नाही"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"बाह्य डिस्प्ले"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index e21daa2..651d498 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"menghantar imej"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Menyimpan tangkapan skrin..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Menyimpan tangkapan skrin ke profil kerja…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Tangkapan skrin disimpan"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Tidak dapat menyimpan tangkapan skrin"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Paparan Luaran"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Gandingkan peranti baharu"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menggandingkan peranti baharu"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat mengemaskinikan pratetapan"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Nyahsekat mikrofon peranti?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Nyahsekat kamera peranti?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Nyahsekat kamera dan mikrofon peranti?"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 000d7d3..c3c4205 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ပုံပို့ထားသည်"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား သိမ်းဆည်းပါမည်"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"အလုပ်ပရိုဖိုင်တွင် ဖန်သားပြင်ဓာတ်ပုံ သိမ်းနေသည်…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"ဖန်သားပြင်ဓာတ်ပုံကို သီးသန့်ပရိုဖိုင်တွင် သိမ်းနေသည်"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"ဖန်သားပြင်ဓာတ်ပုံကို သိမ်းပြီးပါပြီ"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"မျက်နှာပြင်ပုံကို သိမ်း၍မရပါ"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ပြင်ပဖန်သားပြင်"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3fdb8f1..edfbf09 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -76,6 +76,8 @@
<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>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<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_external_display_indication" msgid="6555673132061101936">"Ekstern skjerm"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Koble til en ny enhet"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klikk for å koble til en ny enhet"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kunne ikke oppdatere forhåndsinnstillingen"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du oppheve blokkeringen av enhetsmikrofonen?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du oppheve blokkeringen av enhetskameraet?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du oppheve blokkeringen av enhetskameraet og -mikrofonen?"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index fe4b412..aa7e314 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"कुनै छवि पठाइयो"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रिनसट बचत गर्दै…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"कार्य प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"निजी प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"स्क्रिनसट सेभ गरियो"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"स्क्रिनसट सुरक्षित गर्न सकिएन"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"बाह्य डिस्प्ले"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index add74db..3b460e5 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"heeft een afbeelding gestuurd"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Screenshot opslaan..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Screenshot opslaan in werkprofiel…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Screenshot opslaan in privéprofiel"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Screenshot opgeslagen"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Kan screenshot niet opslaan"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Extern scherm"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Nieuw apparaat koppelen"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nieuw apparaat te koppelen"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kan voorinstelling niet updaten"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Microfoon van apparaat niet meer blokkeren?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Apparaatcamera niet meer blokkeren?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blokkeren van apparaatcamera en -microfoon opheffen?"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 6a93557..f6650ee 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ଏକ ଛବି ପଠାଯାଇଛି"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ କରାଯାଉଛି…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ୱାର୍କ ପ୍ରୋଫାଇଲରେ ସ୍କ୍ରିନସଟ ସେଭ କରାଯାଉଛି…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ ହୋଇଛି"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ସ୍କ୍ରୀନ୍ଶଟ୍ ସେଭ୍ କରିହେବ ନାହିଁ"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେ"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index c908618..3886e78 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ਚਿੱਤਰ ਭੇਜਿਆ ਗਿਆ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸੁਰੱਖਿਅਤ ਕਰ ਰਿਹਾ ਹੈ…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਰੱਖਿਅਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"ਬਾਹਰੀ ਡਿਸਪਲੇ"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index a13a1d6..c8422cb 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"wysłano obraz"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Zapisywanie zrzutu ekranu..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Zapisuję zrzut ekranu w profilu służbowym…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Zrzut ekranu został zapisany"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Nie udało się zapisać zrzutu ekranu"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Wyświetlacz zewnętrzny"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sparuj nowe urządzenie"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknij, aby sparować nowe urządzenie"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokować aparat i mikrofon urządzenia?"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index da72fd5..e72b45a 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Salvando captura de tela..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvando captura de tela no perfil de trabalho…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Salvando captura de tela no perfil particular"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Captura de tela salva"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Falha ao salvar a captura de tela"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Tela externa"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Parear novo dispositivo"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1d9a8da..1912b7e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"A guardar captura de ecrã..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"A guardar captura de ecrã no perfil de trabalho…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"A guardar a captura de ecrã em privado"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Captura de ecrã guardada"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Não foi possível guardar a captura de ecrã"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ecrã externo"</string>
@@ -278,7 +279,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desassociar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Reativar amanhã automaticamente"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"As 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_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>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"Partilha de áudio"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="8626191139359072540">"A partilhar áudio"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sincronizar novo dispositivo"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para sincronizar um novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmara do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Quer desbloquear a câmara e o microfone?"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index da72fd5..e72b45a 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Salvando captura de tela..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvando captura de tela no perfil de trabalho…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Salvando captura de tela no perfil particular"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Captura de tela salva"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Falha ao salvar a captura de tela"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Tela externa"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Parear novo dispositivo"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index f0f5987..b399cfa 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a trimis o imagine"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Se salvează captura de ecran..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Se salvează captura în profilul de serviciu…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Captură de ecran salvată"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Nu s-a putut salva captura de ecran"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Afișaj extern"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Asociază un nou dispozitiv"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Dă clic pentru a asocia un nou dispozitiv"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nu s-a putut actualiza presetarea"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblochezi microfonul dispozitivului?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblochezi camera dispozitivului?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblochezi camera și microfonul dispozitivului?"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index bb79bc2..a79818f 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"отправлено изображение"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Сохранение..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Сохранение скриншота в рабочем профиле…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Скриншот сохранен"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Не удалось сохранить скриншот"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Внешний дисплей"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index ad801c2..28d3220 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"රූපයක් එවන ලදී"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"තිර රුව සුරැකෙමින් පවතී…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"කාර්යාල පැතිකඩ වෙත තිර රුව සුරකිමින්…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"තිර රුව සුරකින ලදී"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"තිර රුව සුරැකිය නොහැකි විය"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"බාහිර සංදර්ශකය"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 5631ab0..051690b 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"odoslal(a) obrázok"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Prebieha ukladanie snímky obrazovky..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ukladá sa snímka obrazovky do pracovného profilu…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Snímka obrazovky bola uložená"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Snímku obrazovky sa nepodarilo uložiť"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Externá obrazovka"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Spárovať nové zariadenie"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zariadenie"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Predvoľbu sa nepodarilo aktualizovať"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Chcete odblokovať mikrofón zariadenia?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Chcete odblokovať kameru zariadenia?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Chcete odblokovať fotoaparát a mikrofón zariadenia?"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index a6b31c9..a3e4487 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslal(-a) sliko"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Shranjevanje posnetka zaslona ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Shranjevanje posnetka zaslona v delovni profil …"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Shranjevanje posnetka zaslona v zasebni profil"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Posnetek zaslona je shranjen"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Posnetka zaslona ni bilo mogoče shraniti"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Zunanji zaslon"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Seznanitev nove naprave"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite za seznanitev nove naprave"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Prednastavljenih vrednosti ni bilo mogoče posodobiti"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite odblokirati mikrofon v napravi?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite odblokirati fotoaparat v napravi?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite odblokirati fotoaparat in mikrofon v napravi?"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index acbf234..b06890d 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"dërgoi një imazh"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Po ruan pamjen e ekranit…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pamja e ekranit po ruhet te profili i punës…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Pamja e ekranit u ruajt"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Pamja e ekranit nuk mund të ruhej"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ekrani i jashtëm"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Çifto pajisje të re"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliko për të çiftuar një pajisje të re"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Paravendosja nuk mund të përditësohej"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Të zhbllokohet mikrofoni i pajisjes?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Të zhbllokohet kamera e pajisjes?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Të zhbllokohen kamera dhe mikrofoni i pajisjes?"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index d21536b..13bf885 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"је послао/ла слику"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Чување снимка екрана..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Снимак екрана се чува на пословном профилу…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Снимак екрана је сачуван"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Чување снимка екрана није успело"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Спољни екран"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 95c5e15..2fec9aa 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har skickat en bild"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Skärmbilden sparas ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sparar skärmbild i jobbprofilen …"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Skärmbilden har sparats"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Det gick inte att spara skärmbilden"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Extern skärm"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Parkoppla en ny enhet"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicka för att parkoppla en ny enhet"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Det gick inte att uppdatera förinställningen"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vill du återaktivera enhetens mikrofon?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vill du återaktivera enhetens kamera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vill du återaktivera enhetens kamera och mikrofon?"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index fab95f0..1be2de1 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"imetuma picha"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Inahifadhi picha ya skrini..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Inahifadhi picha ya skrini kwenye wasifu wa kazini…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Imehifadhi picha ya skrini"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Imeshindwa kuhifadhi picha ya skrini"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Skrini ya Nje"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Unganisha kifaa kipya"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Bofya ili uunganishe kifaa kipya"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Ungependa kuwacha kuzuia kamera na maikrofoni ya kifaa?"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index d8e6892..f716e61 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"படம் அனுப்பப்பட்டது"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ஸ்க்ரீன் ஷாட்டைச் சேமிக்கிறது…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"பணிக் கணக்கில் ஸ்கிரீன்ஷாட் சேமிக்கப்படுகிறது…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"ஸ்கிரீன்ஷாட் சேமிக்கப்பட்டது"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"ஸ்கிரீன் ஷாட்டைச் சேமிக்க முடியவில்லை"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"வெளித் திரை"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 77c89c0..241e952 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ఇమేజ్ను పంపారు"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"స్క్రీన్షాట్ను సేవ్ చేస్తోంది…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"స్క్రీన్షాట్ను వర్క్ ప్రొఫైల్కు సేవ్ చేస్తోంది…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"స్క్రీన్షాట్ సేవ్ చేయబడింది"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"స్క్రీన్షాట్ని సేవ్ చేయడం సాధ్యం కాలేదు"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"వెలుపలి డిస్ప్లే"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 0800a26..b063a8f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ส่งรูปภาพ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"กำลังบันทึกภาพหน้าจอ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"กำลังบันทึกภาพหน้าจอไปยังโปรไฟล์งาน…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"บันทึกภาพหน้าจอแล้ว"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"บันทึกภาพหน้าจอไม่ได้"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"จอแสดงผลภายนอก"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index a8cba0b..aabba45 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"nagpadala ng larawan"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Sine-save ang screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sine-save ang screenshot sa profile sa trabaho…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Sine-save ang screenshot sa pribado"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Na-save ang screenshot"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Hindi ma-save ang screenshot"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"External na Display"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Magpares ng bagong device"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"I-click para magpares ng bagong device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hindi ma-update ang preset"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"I-unblock ang mikropono ng device?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"I-unblock ang camera ng device?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"I-unblock ang camera at mikropono ng device?"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d3fceeb..9bc0cc0 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"bir resim gönderildi"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Ekran görüntüsü kaydediliyor..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ekran görüntüsü iş profiline kaydediliyor…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Ekran görüntüsü kaydedildi"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Ekran görüntüsü kaydedilemedi"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Harici Ekran"</string>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Yeni cihaz eşle"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz eşlemek için tıklayın"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncellenemedi"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonunun engellemesi kaldırılsın mı?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerasının engellemesi kaldırılsın mı?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası ile mikrofonunun engellemesi kaldırılsın mı?"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 662031c..2f64812 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"надіслане зображення"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Збереження знімка екрана..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Зберігання знімка екрана в робочому профілі…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Знімок екрана збережено"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Не вдалося зберегти знімок екрана"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Зовнішній дисплей"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 24a3eb0..e8d2cf4 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ایک تصویر بھیجی"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"اسکرین شاٹ محفوظ ہو رہا ہے…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"اسکرین شاٹ دفتری پروفائل میں محفوظ کیا جا رہا ہے…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"اسکرین شاٹ محفوظ ہو گیا"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"اسکرین شاٹ کو محفوظ نہیں کیا جا سکا"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"خارجی ڈسپلے"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 5cdff8b..55bdd84 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"rasm yuborildi"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Skrinshot saqlanmoqda…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Skrinshot ish profiliga saqlanmoqda…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Skrinshot shaxsiy profilga saqlanmoqda"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Skrinshot saqlandi"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Skrinshot saqlanmadi"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Tashqi displey"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Yangi qurilmani ulash"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yangi qurilmani ulash uchun bosing"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Qurilma kamerasi va mikrofoni blokdan chiqarilsinmi?"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 7c91916..fb1f28c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"đã gửi hình ảnh"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Đang lưu ảnh chụp màn hình..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Đang lưu ảnh chụp màn hình vào hồ sơ công việc…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Đang lưu ảnh chụp màn hình vào hồ sơ riêng tư"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"Đã lưu ảnh chụp màn hình"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Không thể lưu ảnh chụp màn hình"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Màn hình bên ngoài"</string>
@@ -371,6 +372,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Ghép nối thiết bị mới"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Nhấp để ghép nối thiết bị mới"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Không cập nhật được giá trị đặt trước"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Bỏ chặn micrô của thiết bị?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Bỏ chặn camera của thiết bị?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Bỏ chặn máy ảnh và micrô của thiết bị?"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index dda17d4..810fa4a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"发送了一张图片"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"正在保存屏幕截图..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"正在将屏幕截图保存到工作资料…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"已保存屏幕截图"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"无法保存屏幕截图"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"外部显示屏"</string>
@@ -371,6 +373,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index f48d322..8523972 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"已傳送圖片"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"正在儲存螢幕擷取畫面..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"正在將螢幕截圖儲存至工作設定檔…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"正在將螢幕截圖儲存至個人設定檔"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"螢幕擷取畫面已儲存"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"無法儲存螢幕擷取畫面"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"外部顯示屏"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index af1d915..8d5cad4 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -76,6 +76,7 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"傳送了一張圖片"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"正在儲存螢幕截圖…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"正在將螢幕截圖儲存到工作資料夾…"</string>
+ <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"正在將螢幕截圖儲存到個人資料夾"</string>
<string name="screenshot_saved_title" msgid="8893267638659083153">"螢幕截圖已儲存"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"無法儲存螢幕截圖"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"外接螢幕"</string>
@@ -278,7 +279,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"取消連結"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"啟用"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"明天自動重新開啟"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"「快速分享」和「尋找我的裝置」等功能需要藍牙"</string>
+ <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"「快速分享」和「尋找我的裝置」等功能都需要使用藍牙技術"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"藍牙會在明天早上開啟"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"音訊分享"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="8626191139359072540">"正在分享音訊"</string>
@@ -371,6 +372,8 @@
<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>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index a4673db..f253d4e 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -76,6 +76,8 @@
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"uthumele isithombe"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Ilondoloz umfanekiso weskrini..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ilondoloza isithombe-skrini kuphrofayela yomsebenzi…"</string>
+ <!-- no translation found for screenshot_saving_private_profile (8934706048497093297) -->
+ <skip />
<string name="screenshot_saved_title" msgid="8893267638659083153">"Isithombe-skrini silondoloziwe"</string>
<string name="screenshot_failed_title" msgid="3259148215671936891">"Ayikwazanga ukulondoloza isithombe-skrini"</string>
<string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Isiboniso Sangaphandle"</string>
@@ -271,7 +273,7 @@
<string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Thepha ukuze uxhumae noma ungaxhumi idivaysi"</string>
<string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Bhangqa idivayisi entsha"</string>
<string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Buka konke"</string>
- <string name="turn_on_bluetooth" msgid="5681370462180289071">"Sebenzisa i-Bluetooth"</string>
+ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Sebenzisa iBluetooth"</string>
<string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ixhunyiwe"</string>
<string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Ukwabelana Ngokuqoshiwe"</string>
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ilondoloziwe"</string>
@@ -279,7 +281,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"yenza kusebenze"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Vula ngokuzenzekela futhi kusasa"</string>
<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">"I-Bluetooth izovuleka kusasa ekuseni"</string>
+ <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"IBluetooth izovuleka kusasa ekuseni"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="4499275822759907822">"Ukwabelana Ngokuqoshiwe"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="8626191139359072540">"Ukwabelana 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>
@@ -371,6 +373,8 @@
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Bhangqa idivayisi entsha"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Chofoza ukuze ubhangqe idivayisi entsha"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ayikwazanga ukubuyekeza ukusetha ngaphambilini"</string>
+ <!-- no translation found for hearing_devices_preset_label (7878267405046232358) -->
+ <skip />
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vulela imakrofoni yedivayisi?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vulela ikhamera yedivayisi?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vulela ikhamera yedivayisi nemakrofoni?"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 02b74ce..7d7a5d4 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1772,10 +1772,10 @@
<dimen name="bluetooth_dialog_scroll_view_min_height_with_auto_on">350dp</dimen>
<!-- Hearing devices dialog related dimensions -->
+ <dimen name="hearing_devices_layout_margin">12dp</dimen>
<dimen name="hearing_devices_preset_spinner_height">72dp</dimen>
- <dimen name="hearing_devices_preset_spinner_margin">24dp</dimen>
<dimen name="hearing_devices_preset_spinner_text_padding_start">20dp</dimen>
- <dimen name="hearing_devices_preset_spinner_text_padding_end">80dp</dimen>
+ <dimen name="hearing_devices_preset_spinner_text_padding_vertical">15dp</dimen>
<dimen name="hearing_devices_preset_spinner_arrow_size">24dp</dimen>
<dimen name="hearing_devices_preset_spinner_background_radius">28dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index abfdc2a..6f2806d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -913,8 +913,10 @@
<string name="quick_settings_pair_hearing_devices">Pair new device</string>
<!-- QuickSettings: Content description of the hearing devices dialog pair new device [CHAR LIMIT=NONE] -->
<string name="accessibility_hearing_device_pair_new_device">Click to pair new device</string>
- <!-- Message when selecting hearing aids presets failed. [CHAR LIMIT=NONE] -->
+ <!-- QuickSettings: Message when selecting hearing aids presets failed. [CHAR LIMIT=NONE] -->
<string name="hearing_devices_presets_error">Couldn\'t update preset</string>
+ <!-- QuickSettings: Title for hearing aids presets. Preset is a set of hearing aid settings. User can apply different settings in different environments (e.g. Outdoor, Restaurant, Home) [CHAR LIMIT=40]-->
+ <string name="hearing_devices_preset_label">Preset</string>
<!--- Title of dialog triggered if the microphone is disabled but an app tried to access it. [CHAR LIMIT=150] -->
<string name="sensor_privacy_start_use_mic_dialog_title">Unblock device microphone?</string>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
index 7b5a09c..28dd233 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -32,6 +32,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.Visibility;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
@@ -208,6 +209,10 @@
}
mMainHandler.post(() -> {
mDeviceListAdapter.refreshDeviceItemList(mHearingDeviceItemList);
+ final List<BluetoothHapPresetInfo> presetInfos =
+ mPresetsController.getAllPresetInfo();
+ final int activePresetIndex = mPresetsController.getActivePresetIndex();
+ refreshPresetInfoAdapter(presetInfos, activePresetIndex);
mPresetSpinner.setVisibility(
(activeHearingDevice != null && !mPresetInfoAdapter.isEmpty()) ? VISIBLE
: GONE);
@@ -295,10 +300,23 @@
mHearingDeviceItemList);
mPresetsController.setActiveHearingDevice(activeHearingDevice);
- mPresetInfoAdapter = new ArrayAdapter<>(dialog.getContext(),
- android.R.layout.simple_spinner_dropdown_item);
- mPresetInfoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mPresetInfoAdapter = new ArrayAdapter<String>(dialog.getContext(),
+ R.layout.hearing_devices_preset_spinner_selected,
+ R.id.hearing_devices_preset_option_text);
+ mPresetInfoAdapter.setDropDownViewResource(
+ R.layout.hearing_devices_preset_dropdown_item);
mPresetSpinner.setAdapter(mPresetInfoAdapter);
+
+ // disable redundant Touch & Hold accessibility action for Switch Access
+ mPresetSpinner.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(@NonNull View host,
+ @NonNull AccessibilityNodeInfo info) {
+ info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ }
+ });
+
mPresetSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index 6f20a8d..d522c7e 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -20,6 +20,7 @@
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.CoreStartable
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
import com.android.systemui.dagger.SysUISingleton
@@ -32,10 +33,13 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.statusbar.NotificationShadeWindowController
+import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.util.kotlin.emitOnStart
+import com.android.systemui.util.kotlin.getValue
import com.android.systemui.util.kotlin.sample
import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
import com.android.systemui.util.settings.SystemSettings
+import java.util.Optional
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
@@ -64,9 +68,11 @@
constructor(
private val dockManager: DockManager,
private val communalInteractor: CommunalInteractor,
+ private val communalSceneInteractor: CommunalSceneInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val keyguardInteractor: KeyguardInteractor,
private val systemSettings: SystemSettings,
+ centralSurfacesOpt: Optional<CentralSurfaces>,
private val notificationShadeWindowController: NotificationShadeWindowController,
@Application private val applicationScope: CoroutineScope,
@Background private val bgScope: CoroutineScope,
@@ -78,13 +84,15 @@
private var isDreaming: Boolean = false
+ private val centralSurfaces: CentralSurfaces? by centralSurfacesOpt
+
override fun start() {
// Handle automatically switching based on keyguard state.
keyguardTransitionInteractor.startedKeyguardTransitionStep
.mapLatest(::determineSceneAfterTransition)
.filterNotNull()
.onEach { nextScene ->
- communalInteractor.changeScene(nextScene, CommunalTransitionKeys.SimpleFade)
+ communalSceneInteractor.changeScene(nextScene, CommunalTransitionKeys.SimpleFade)
}
.launchIn(applicationScope)
@@ -124,7 +132,7 @@
// app is updated by the Play store, a new timeout should be started.
bgScope.launch {
combine(
- communalInteractor.desiredScene,
+ communalSceneInteractor.currentScene,
// Emit a value on start so the combine starts.
communalInteractor.userActivity.emitOnStart()
) { scene, _ ->
@@ -140,19 +148,19 @@
}
bgScope.launch {
keyguardInteractor.isDreaming
- .sample(communalInteractor.desiredScene, ::Pair)
+ .sample(communalSceneInteractor.currentScene, ::Pair)
.collectLatest { (isDreaming, scene) ->
this@CommunalSceneStartable.isDreaming = isDreaming
if (scene == CommunalScenes.Communal && isDreaming && timeoutJob == null) {
// If dreaming starts after timeout has expired, ex. if dream restarts under
// the hub, just close the hub immediately.
- communalInteractor.changeScene(CommunalScenes.Blank)
+ communalSceneInteractor.changeScene(CommunalScenes.Blank)
}
}
}
bgScope.launch {
- communalInteractor.isIdleOnCommunal.collectLatest {
+ communalSceneInteractor.isIdleOnCommunal.collectLatest {
withContext(mainDispatcher) {
notificationShadeWindowController.setGlanceableHubShowing(it)
}
@@ -171,7 +179,7 @@
bgScope.launch {
delay(screenTimeout.milliseconds)
if (isDreaming) {
- communalInteractor.changeScene(CommunalScenes.Blank)
+ communalSceneInteractor.changeScene(CommunalScenes.Blank)
}
timeoutJob = null
}
@@ -184,11 +192,15 @@
val to = lastStartedTransition.to
val from = lastStartedTransition.from
val docked = dockManager.isDocked
+ val launchingActivityOverLockscreen =
+ centralSurfaces?.isLaunchingActivityOverLockscreen ?: false
return when {
- to == KeyguardState.OCCLUDED -> {
+ to == KeyguardState.OCCLUDED && !launchingActivityOverLockscreen -> {
// Hide communal when an activity is started on keyguard, to ensure the activity
- // underneath the hub is shown.
+ // 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.
CommunalScenes.Blank
}
to == KeyguardState.GLANCEABLE_HUB && from == KeyguardState.OCCLUDED -> {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepositoryModule.kt
index 1de3459..7f137f3 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepositoryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepositoryModule.kt
@@ -21,5 +21,5 @@
@Module
interface CommunalRepositoryModule {
- @Binds fun communalRepository(impl: CommunalRepositoryImpl): CommunalRepository
+ @Binds fun communalRepository(impl: CommunalSceneRepositoryImpl): CommunalSceneRepository
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
rename to packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
index 8bfd8d9..d6d08b4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
@@ -36,7 +36,7 @@
import kotlinx.coroutines.flow.stateIn
/** Encapsulates the state of communal mode. */
-interface CommunalRepository {
+interface CommunalSceneRepository {
/**
* Target scene as requested by the underlying [SceneTransitionLayout] or through [changeScene].
*/
@@ -48,6 +48,9 @@
/** Updates the requested scene. */
fun changeScene(toScene: SceneKey, transitionKey: TransitionKey? = null)
+ /** Immediately snaps to the desired scene. */
+ fun snapToScene(toScene: SceneKey)
+
/**
* Updates the transition state of the hub [SceneTransitionLayout].
*
@@ -58,12 +61,12 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
-class CommunalRepositoryImpl
+class CommunalSceneRepositoryImpl
@Inject
constructor(
@Background backgroundScope: CoroutineScope,
@Communal private val sceneDataSource: SceneDataSource,
-) : CommunalRepository {
+) : CommunalSceneRepository {
override val currentScene: StateFlow<SceneKey> = sceneDataSource.currentScene
@@ -82,6 +85,10 @@
sceneDataSource.changeScene(toScene, transitionKey)
}
+ override fun snapToScene(toScene: SceneKey) {
+ sceneDataSource.snapToScene(toScene)
+ }
+
/**
* Updates the transition state of the hub [SceneTransitionLayout].
*
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 9599a88..2be28ca 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
@@ -29,7 +29,6 @@
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.communal.data.repository.CommunalMediaRepository
import com.android.systemui.communal.data.repository.CommunalPrefsRepository
-import com.android.systemui.communal.data.repository.CommunalRepository
import com.android.systemui.communal.data.repository.CommunalWidgetRepository
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.domain.model.CommunalContentModel.WidgetContent
@@ -97,7 +96,6 @@
@Application val applicationScope: CoroutineScope,
@Background val bgDispatcher: CoroutineDispatcher,
broadcastDispatcher: BroadcastDispatcher,
- private val communalRepository: CommunalRepository,
private val widgetRepository: CommunalWidgetRepository,
private val communalPrefsRepository: CommunalPrefsRepository,
mediaRepository: CommunalMediaRepository,
@@ -110,6 +108,7 @@
private val userTracker: UserTracker,
private val activityStarter: ActivityStarter,
private val userManager: UserManager,
+ private val communalSceneInteractor: CommunalSceneInteractor,
sceneInteractor: SceneInteractor,
@CommunalLog logBuffer: LogBuffer,
@CommunalTableLog tableLogBuffer: TableLogBuffer,
@@ -174,15 +173,19 @@
*
* If [isCommunalAvailable] is false, will return [CommunalScenes.Blank]
*/
- val desiredScene: Flow<SceneKey> =
- communalRepository.currentScene.combine(isCommunalAvailable) { scene, available ->
- if (available) scene else CommunalScenes.Blank
- }
+ @Deprecated(
+ "Use com.android.systemui.communal.domain.interactor.CommunalSceneInteractor instead"
+ )
+ val desiredScene: Flow<SceneKey> = communalSceneInteractor.currentScene
/** Transition state of the hub mode. */
- val transitionState: StateFlow<ObservableTransitionState> = communalRepository.transitionState
+ @Deprecated(
+ "Use com.android.systemui.communal.domain.interactor.CommunalSceneInteractor instead"
+ )
+ val transitionState: StateFlow<ObservableTransitionState> =
+ communalSceneInteractor.transitionState
- val _userActivity: MutableSharedFlow<Unit> =
+ private val _userActivity: MutableSharedFlow<Unit> =
MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
val userActivity: Flow<Unit> = _userActivity.asSharedFlow()
@@ -212,32 +215,18 @@
*
* Note that you must call is with `null` when the UI is done or risk a memory leak.
*/
- fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) {
- communalRepository.setTransitionState(transitionState)
- }
+ @Deprecated(
+ "Use com.android.systemui.communal.domain.interactor.CommunalSceneInteractor instead"
+ )
+ fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) =
+ communalSceneInteractor.setTransitionState(transitionState)
/** Returns a flow that tracks the progress of transitions to the given scene from 0-1. */
+ @Deprecated(
+ "Use com.android.systemui.communal.domain.interactor.CommunalSceneInteractor instead"
+ )
fun transitionProgressToScene(targetScene: SceneKey) =
- transitionState
- .flatMapLatest { state ->
- when (state) {
- is ObservableTransitionState.Idle ->
- flowOf(CommunalTransitionProgress.Idle(state.currentScene))
- is ObservableTransitionState.Transition ->
- if (state.toScene == targetScene) {
- state.progress.map {
- CommunalTransitionProgress.Transition(
- // Clamp the progress values between 0 and 1 as actual progress
- // values can be higher than 0 or lower than 1 due to a fling.
- progress = it.coerceIn(0.0f, 1.0f)
- )
- }
- } else {
- flowOf(CommunalTransitionProgress.OtherTransition)
- }
- }
- }
- .distinctUntilChanged()
+ communalSceneInteractor.transitionProgressToScene(targetScene)
/**
* Flow that emits a boolean if the communal UI is the target scene, ie. the [desiredScene] is
@@ -283,34 +272,30 @@
* This will not be true while transitioning to the hub and will turn false immediately when a
* swipe to exit the hub starts.
*/
- val isIdleOnCommunal: StateFlow<Boolean> =
- communalRepository.transitionState
- .map {
- it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Communal
- }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.Eagerly,
- initialValue = false,
- )
+ @Deprecated(
+ "Use com.android.systemui.communal.domain.interactor.CommunalSceneInteractor instead"
+ )
+ val isIdleOnCommunal: StateFlow<Boolean> = communalSceneInteractor.isIdleOnCommunal
/**
* Flow that emits a boolean if any portion of the communal UI is visible at all.
*
* This flow will be true during any transition and when idle on the communal scene.
*/
- val isCommunalVisible: Flow<Boolean> =
- communalRepository.transitionState.map {
- !(it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Blank)
- }
+ @Deprecated(
+ "Use com.android.systemui.communal.domain.interactor.CommunalSceneInteractor instead"
+ )
+ val isCommunalVisible: Flow<Boolean> = communalSceneInteractor.isCommunalVisible
/**
* Asks for an asynchronous scene witch to [newScene], which will use the corresponding
* installed transition or the one specified by [transitionKey], if provided.
*/
- fun changeScene(newScene: SceneKey, transitionKey: TransitionKey? = null) {
- communalRepository.changeScene(newScene, transitionKey)
- }
+ @Deprecated(
+ "Use com.android.systemui.communal.domain.interactor.CommunalSceneInteractor instead"
+ )
+ fun changeScene(newScene: SceneKey, transitionKey: TransitionKey? = null) =
+ communalSceneInteractor.changeScene(newScene, transitionKey)
fun setEditModeOpen(isOpen: Boolean) {
_editModeOpen.value = isOpen
@@ -579,17 +564,3 @@
}
}
}
-
-/** Simplified transition progress data class for tracking a single transition between scenes. */
-sealed class CommunalTransitionProgress {
- /** No transition/animation is currently running. */
- data class Idle(val scene: SceneKey) : CommunalTransitionProgress()
-
- /** There is a transition animating to the expected scene. */
- data class Transition(
- val progress: Float,
- ) : CommunalTransitionProgress()
-
- /** There is a transition animating to a scene other than the expected scene. */
- data object OtherTransition : CommunalTransitionProgress()
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
new file mode 100644
index 0000000..5cfe979
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
@@ -0,0 +1,127 @@
+/*
+ * 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.communal.domain.interactor
+
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.TransitionKey
+import com.android.systemui.communal.data.repository.CommunalSceneRepository
+import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+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.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class CommunalSceneInteractor
+@Inject
+constructor(
+ @Application private val applicationScope: CoroutineScope,
+ private val communalSceneRepository: CommunalSceneRepository,
+) {
+ /**
+ * Asks for an asynchronous scene witch to [newScene], which will use the corresponding
+ * installed transition or the one specified by [transitionKey], if provided.
+ */
+ fun changeScene(newScene: SceneKey, transitionKey: TransitionKey? = null) {
+ communalSceneRepository.changeScene(newScene, transitionKey)
+ }
+
+ /** Immediately snaps to the new scene. */
+ fun snapToScene(newScene: SceneKey) {
+ communalSceneRepository.snapToScene(newScene)
+ }
+
+ /**
+ * Target scene as requested by the underlying [SceneTransitionLayout] or through [changeScene].
+ */
+ val currentScene: Flow<SceneKey> = communalSceneRepository.currentScene
+
+ /** Transition state of the hub mode. */
+ val transitionState: StateFlow<ObservableTransitionState> =
+ communalSceneRepository.transitionState
+
+ /**
+ * Updates the transition state of the hub [SceneTransitionLayout].
+ *
+ * Note that you must call is with `null` when the UI is done or risk a memory leak.
+ */
+ fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) {
+ communalSceneRepository.setTransitionState(transitionState)
+ }
+
+ /** Returns a flow that tracks the progress of transitions to the given scene from 0-1. */
+ fun transitionProgressToScene(targetScene: SceneKey) =
+ transitionState
+ .flatMapLatest { state ->
+ when (state) {
+ is ObservableTransitionState.Idle ->
+ flowOf(CommunalTransitionProgressModel.Idle(state.currentScene))
+ is ObservableTransitionState.Transition ->
+ if (state.toScene == targetScene) {
+ state.progress.map {
+ CommunalTransitionProgressModel.Transition(
+ // Clamp the progress values between 0 and 1 as actual progress
+ // values can be higher than 0 or lower than 1 due to a fling.
+ progress = it.coerceIn(0.0f, 1.0f)
+ )
+ }
+ } else {
+ flowOf(CommunalTransitionProgressModel.OtherTransition)
+ }
+ }
+ }
+ .distinctUntilChanged()
+
+ /**
+ * Flow that emits a boolean if the communal UI is fully visible and not in transition.
+ *
+ * This will not be true while transitioning to the hub and will turn false immediately when a
+ * swipe to exit the hub starts.
+ */
+ val isIdleOnCommunal: StateFlow<Boolean> =
+ transitionState
+ .map {
+ it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Communal
+ }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue = false,
+ )
+
+ /**
+ * Flow that emits a boolean if any portion of the communal UI is visible at all.
+ *
+ * This flow will be true during any transition and when idle on the communal scene.
+ */
+ val isCommunalVisible: Flow<Boolean> =
+ transitionState.map {
+ !(it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Blank)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalTransitionProgressModel.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalTransitionProgressModel.kt
new file mode 100644
index 0000000..e3187c2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalTransitionProgressModel.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.communal.domain.model
+
+import com.android.compose.animation.scene.SceneKey
+
+/** Simplified transition progress data class for tracking a single transition between scenes. */
+sealed interface CommunalTransitionProgressModel {
+ /** No transition/animation is currently running. */
+ data class Idle(val scene: SceneKey) : CommunalTransitionProgressModel
+
+ /** There is a transition animating to the expected scene. */
+ data class Transition(
+ val progress: Float,
+ ) : CommunalTransitionProgressModel
+
+ /** There is a transition animating to a scene other than the expected scene. */
+ data object OtherTransition : CommunalTransitionProgressModel
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
index a3c61a4..73cfb52 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
@@ -26,4 +26,6 @@
object CommunalTransitionKeys {
/** Fades the glanceable hub without any translation */
val SimpleFade = TransitionKey("SimpleFade")
+ /** Immediately transitions without any delay */
+ val Immediately = TransitionKey("Immediately")
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
index db251fd..3d9e861 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -23,6 +23,7 @@
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.media.controls.ui.view.MediaHost
@@ -33,10 +34,11 @@
/** The base view model for the communal hub. */
abstract class BaseCommunalViewModel(
+ private val communalSceneInteractor: CommunalSceneInteractor,
private val communalInteractor: CommunalInteractor,
val mediaHost: MediaHost,
) {
- val currentScene: Flow<SceneKey> = communalInteractor.desiredScene
+ val currentScene: Flow<SceneKey> = communalSceneInteractor.currentScene
/** Whether communal hub should be focused by accessibility tools. */
open val isFocusable: Flow<Boolean> = MutableStateFlow(false)
@@ -58,7 +60,7 @@
}
fun changeScene(scene: SceneKey, transitionKey: TransitionKey? = null) {
- communalInteractor.changeScene(scene, transitionKey)
+ communalSceneInteractor.changeScene(scene, transitionKey)
}
/**
@@ -67,7 +69,7 @@
* Note that you must call is with `null` when the UI is done or risk a memory leak.
*/
fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) {
- communalInteractor.setTransitionState(transitionState)
+ communalSceneInteractor.setTransitionState(transitionState)
}
/**
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 650852c..bc65ccb 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.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.log.CommunalUiEvent
@@ -50,13 +51,14 @@
class CommunalEditModeViewModel
@Inject
constructor(
+ communalSceneInteractor: CommunalSceneInteractor,
private val communalInteractor: CommunalInteractor,
private val communalSettingsInteractor: CommunalSettingsInteractor,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
private val uiEventLogger: UiEventLogger,
@CommunalLog logBuffer: LogBuffer,
@Background private val backgroundDispatcher: CoroutineDispatcher,
-) : BaseCommunalViewModel(communalInteractor, mediaHost) {
+) : BaseCommunalViewModel(communalSceneInteractor, communalInteractor, mediaHost) {
private val logger = Logger(logBuffer, "CommunalEditModeViewModel")
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 97db43b..7f3a2dc 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
@@ -20,6 +20,7 @@
import android.view.View
import android.view.accessibility.AccessibilityNodeInfo
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.dagger.SysUISingleton
@@ -65,12 +66,13 @@
@Main private val resources: Resources,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
keyguardInteractor: KeyguardInteractor,
+ communalSceneInteractor: CommunalSceneInteractor,
private val communalInteractor: CommunalInteractor,
tutorialInteractor: CommunalTutorialInteractor,
private val shadeInteractor: ShadeInteractor,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
@CommunalLog logBuffer: LogBuffer,
-) : BaseCommunalViewModel(communalInteractor, mediaHost) {
+) : BaseCommunalViewModel(communalSceneInteractor, communalInteractor, mediaHost) {
private val logger = Logger(logBuffer, "CommunalViewModel")
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt
index b7e8205..058ca4d 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt
@@ -83,7 +83,9 @@
override fun allocateAppWidgetId(): Int {
return super.allocateAppWidgetId().also { appWidgetId ->
backgroundScope.launch {
- observers.forEach { observer -> observer.onAllocateAppWidgetId(appWidgetId) }
+ synchronized(observers) {
+ observers.forEach { observer -> observer.onAllocateAppWidgetId(appWidgetId) }
+ }
}
}
}
@@ -91,18 +93,28 @@
override fun deleteAppWidgetId(appWidgetId: Int) {
super.deleteAppWidgetId(appWidgetId)
backgroundScope.launch {
- observers.forEach { observer -> observer.onDeleteAppWidgetId(appWidgetId) }
+ synchronized(observers) {
+ observers.forEach { observer -> observer.onDeleteAppWidgetId(appWidgetId) }
+ }
}
}
override fun startListening() {
super.startListening()
- backgroundScope.launch { observers.forEach { observer -> observer.onHostStartListening() } }
+ backgroundScope.launch {
+ synchronized(observers) {
+ observers.forEach { observer -> observer.onHostStartListening() }
+ }
+ }
}
override fun stopListening() {
super.stopListening()
- backgroundScope.launch { observers.forEach { observer -> observer.onHostStopListening() } }
+ backgroundScope.launch {
+ synchronized(observers) {
+ observers.forEach { observer -> observer.onHostStopListening() }
+ }
+ }
}
fun addObserver(observer: Observer) {
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 778d8cf..51a3a6d 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
@@ -61,6 +61,7 @@
activityStarter.startPendingIntentMaybeDismissingKeyguard(
pendingIntent,
+ /* dismissShade = */ false,
/* intentSentUiThreadCallback = */ null,
animationController,
fillInIntent,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 93f3793..339e8f0 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -75,7 +75,8 @@
import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.log.dagger.MonitorLog;
import com.android.systemui.log.table.TableLogBuffer;
-import com.android.systemui.mediaprojection.appselector.MediaProjectionModule;
+import com.android.systemui.mediaprojection.MediaProjectionModule;
+import com.android.systemui.mediaprojection.appselector.MediaProjectionActivitiesModule;
import com.android.systemui.mediaprojection.taskswitcher.MediaProjectionTaskSwitcherModule;
import com.android.systemui.model.SceneContainerPlugin;
import com.android.systemui.model.SysUiState;
@@ -225,6 +226,7 @@
KeyguardSectionsModule.class,
LetterboxModule.class,
LogModule.class,
+ MediaProjectionActivitiesModule.class,
MediaProjectionModule.class,
MediaProjectionTaskSwitcherModule.class,
MotionToolModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 956c0f5..f2a544e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -79,6 +79,7 @@
import com.android.systemui.dagger.qualifiers.Application;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor;
import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier;
import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindViewBinder;
import com.android.systemui.keyguard.ui.binder.WindowManagerLockscreenVisibilityViewBinder;
@@ -311,6 +312,7 @@
}
private final WindowManagerOcclusionManager mWmOcclusionManager;
+ private final KeyguardEnabledInteractor mKeyguardEnabledInteractor;
private final Lazy<FoldGracePeriodProvider> mFoldGracePeriodProvider = new Lazy<>() {
@Override
@@ -335,7 +337,8 @@
PowerInteractor powerInteractor,
WindowManagerOcclusionManager windowManagerOcclusionManager,
Lazy<SceneInteractor> sceneInteractorLazy,
- @Main Executor mainExecutor) {
+ @Main Executor mainExecutor,
+ KeyguardEnabledInteractor keyguardEnabledInteractor) {
super();
mKeyguardViewMediator = keyguardViewMediator;
mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
@@ -360,6 +363,7 @@
}
mWmOcclusionManager = windowManagerOcclusionManager;
+ mKeyguardEnabledInteractor = keyguardEnabledInteractor;
}
@Override
@@ -598,6 +602,7 @@
public void setKeyguardEnabled(boolean enabled) {
trace("setKeyguardEnabled enabled" + enabled);
checkPermission();
+ mKeyguardEnabledInteractor.notifyKeyguardEnabled(enabled);
mKeyguardViewMediator.setKeyguardEnabled(enabled);
}
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 8a53dd1..a2bbcad 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
@@ -109,6 +109,19 @@
)
val isKeyguardGoingAway: Flow<Boolean>
+ /**
+ * Whether the keyguard is enabled, per [KeyguardService]. If the keyguard is not enabled, the
+ * lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE.
+ *
+ * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold
+ * permission to do so (such as Phone).
+ *
+ * If the keyguard is disabled while we're locked, we will transition to GONE unless we're in
+ * lockdown mode. If the keyguard is re-enabled, we'll transition back to LOCKSCREEN if we were
+ * locked when it was disabled.
+ */
+ val isKeyguardEnabled: StateFlow<Boolean>
+
/** Is the always-on display available to be used? */
val isAodAvailable: StateFlow<Boolean>
@@ -269,6 +282,9 @@
"'keyguardDoneAnimationsFinished' is when the GONE transition is finished."
)
fun keyguardDoneAnimationsFinished()
+
+ /** Sets whether the keyguard is enabled (see [isKeyguardEnabled]). */
+ fun setKeyguardEnabled(enabled: Boolean)
}
/** Encapsulates application state for the keyguard. */
@@ -439,6 +455,9 @@
awaitClose { keyguardStateController.removeCallback(callback) }
}
+ private val _isKeyguardEnabled = MutableStateFlow(true)
+ override val isKeyguardEnabled: StateFlow<Boolean> = _isKeyguardEnabled.asStateFlow()
+
private val _isDozing = MutableStateFlow(statusBarStateController.isDozing)
override val isDozing: StateFlow<Boolean> = _isDozing.asStateFlow()
@@ -664,6 +683,10 @@
_clockShouldBeCentered.value = shouldBeCentered
}
+ override fun setKeyguardEnabled(enabled: Boolean) {
+ _isKeyguardEnabled.value = enabled
+ }
+
private fun statusBarStateIntToObject(value: Int): StatusBarState {
return when (value) {
0 -> StatusBarState.SHADE
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index a306954..01109af 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -22,6 +22,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode.Companion.isWakeAndUnlock
@@ -50,6 +51,7 @@
private val keyguardInteractor: KeyguardInteractor,
powerInteractor: PowerInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
+ val deviceEntryRepository: DeviceEntryRepository,
) :
TransitionInteractor(
fromState = KeyguardState.AOD,
@@ -125,7 +127,12 @@
val shouldTransitionToOccluded =
!KeyguardWmStateRefactor.isEnabled && isKeyguardOccludedLegacy
- if (canDismissLockscreen) {
+ val shouldTransitionToGone =
+ (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen) ||
+ (KeyguardWmStateRefactor.isEnabled &&
+ !deviceEntryRepository.isLockscreenEnabled())
+
+ if (shouldTransitionToGone) {
startTransitionTo(
toState = KeyguardState.GONE,
)
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 115fc36..7d3de30 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
@@ -22,6 +22,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockMode.Companion.isWakeAndUnlock
@@ -50,6 +51,7 @@
powerInteractor: PowerInteractor,
private val communalInteractor: CommunalInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
+ val deviceEntryRepository: DeviceEntryRepository,
) :
TransitionInteractor(
fromState = KeyguardState.DOZING,
@@ -99,7 +101,9 @@
canTransitionToGoneOnWake,
primaryBouncerShowing) ->
startTransitionTo(
- if (isWakeAndUnlock(biometricUnlockState.mode)) {
+ if (!deviceEntryRepository.isLockscreenEnabled()) {
+ KeyguardState.GONE
+ } else if (isWakeAndUnlock(biometricUnlockState.mode)) {
KeyguardState.GONE
} else if (canTransitionToGoneOnWake) {
KeyguardState.GONE
@@ -145,7 +149,12 @@
!isWakeAndUnlock(biometricUnlockState.mode)
) {
startTransitionTo(
- if (canDismissLockscreen) {
+ if (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen) {
+ KeyguardState.GONE
+ } else if (
+ KeyguardWmStateRefactor.isEnabled &&
+ !deviceEntryRepository.isLockscreenEnabled()
+ ) {
KeyguardState.GONE
} else if (primaryBouncerShowing) {
KeyguardState.PRIMARY_BOUNCER
@@ -153,7 +162,8 @@
KeyguardState.GLANCEABLE_HUB
} else {
KeyguardState.LOCKSCREEN
- }
+ },
+ ownerReason = "waking from dozing"
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index 2b3732f..8ca29c8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -25,6 +25,7 @@
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
@@ -36,6 +37,7 @@
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
@SysUISingleton
@@ -52,6 +54,8 @@
private val communalInteractor: CommunalInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
private val biometricSettingsRepository: BiometricSettingsRepository,
+ private val keyguardRepository: KeyguardRepository,
+ private val keyguardEnabledInteractor: KeyguardEnabledInteractor,
) :
TransitionInteractor(
fromState = KeyguardState.GONE,
@@ -93,6 +97,21 @@
startTransitionTo(to, ownerReason = "User initiated lockdown")
}
}
+
+ scope.launch {
+ keyguardRepository.isKeyguardEnabled
+ .filterRelevantKeyguardStateAnd { enabled -> enabled }
+ .sample(keyguardEnabledInteractor.showKeyguardWhenReenabled)
+ .filter { reshow -> reshow }
+ .collect {
+ startTransitionTo(
+ KeyguardState.LOCKSCREEN,
+ ownerReason =
+ "Keyguard was re-enabled, and we weren't GONE when it " +
+ "was originally disabled"
+ )
+ }
+ }
} else {
scope.launch("$TAG#listenForGoneToLockscreenOrHub") {
keyguardInteractor.isKeyguardShowing
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
index fcf67d5..af1ce2b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
@@ -19,7 +19,7 @@
import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
import com.android.systemui.communal.domain.interactor.CommunalInteractor
-import com.android.systemui.communal.domain.interactor.CommunalTransitionProgress
+import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -71,7 +71,7 @@
if (id == null) {
// No transition started.
if (
- transitionProgress is CommunalTransitionProgress.Transition &&
+ transitionProgress is CommunalTransitionProgressModel.Transition &&
lastStartedState == fromState
) {
transitionId =
@@ -93,7 +93,7 @@
val nextState: TransitionState
val progressFraction: Float
when (transitionProgress) {
- is CommunalTransitionProgress.Idle -> {
+ is CommunalTransitionProgressModel.Idle -> {
if (transitionProgress.scene == toScene) {
nextState = TransitionState.FINISHED
progressFraction = 1f
@@ -102,11 +102,11 @@
progressFraction = 0f
}
}
- is CommunalTransitionProgress.Transition -> {
+ is CommunalTransitionProgressModel.Transition -> {
nextState = TransitionState.RUNNING
progressFraction = transitionProgress.progress
}
- is CommunalTransitionProgress.OtherTransition -> {
+ is CommunalTransitionProgressModel.OtherTransition -> {
// Shouldn't happen but if another transition starts during the
// current one, mark the current one as canceled.
nextState = TransitionState.CANCELED
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
new file mode 100644
index 0000000..8dede01
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
@@ -0,0 +1,92 @@
+/*
+ * 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.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/**
+ * Logic around the keyguard being enabled/disabled, per [KeyguardService]. If the keyguard is not
+ * enabled, the lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE.
+ *
+ * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold
+ * permission to do so (such as Phone). Some CTS tests also disable keyguard in onCreate or onStart
+ * rather than simply dismissing the keyguard or setting up the device to have Security: None, for
+ * reasons unknown.
+ */
+@SysUISingleton
+class KeyguardEnabledInteractor
+@Inject
+constructor(
+ @Application scope: CoroutineScope,
+ val repository: KeyguardRepository,
+ val biometricSettingsRepository: BiometricSettingsRepository,
+ transitionInteractor: KeyguardTransitionInteractor,
+) {
+
+ init {
+ /**
+ * Whenever keyguard is disabled, transition to GONE unless we're in lockdown or already
+ * GONE.
+ */
+ scope.launch {
+ repository.isKeyguardEnabled
+ .filter { enabled -> !enabled }
+ .sampleCombine(
+ biometricSettingsRepository.isCurrentUserInLockdown,
+ transitionInteractor.currentTransitionInfoInternal,
+ )
+ .collect { (_, inLockdown, currentTransitionInfo) ->
+ if (currentTransitionInfo.to != KeyguardState.GONE && !inLockdown) {
+ transitionInteractor.startDismissKeyguardTransition("keyguard disabled")
+ }
+ }
+ }
+ }
+
+ /**
+ * Whether we need to show the keyguard when the keyguard is re-enabled, since we hid it when it
+ * became disabled.
+ */
+ val showKeyguardWhenReenabled: Flow<Boolean> =
+ repository.isKeyguardEnabled
+ // Whenever the keyguard is disabled...
+ .filter { enabled -> !enabled }
+ .sampleCombine(
+ transitionInteractor.currentTransitionInfoInternal,
+ biometricSettingsRepository.isCurrentUserInLockdown
+ )
+ .map { (_, transitionInfo, inLockdown) ->
+ // ...we hide the keyguard, if it's showing and we're not in lockdown. In that case,
+ // we want to remember that and re-show it when keyguard is enabled again.
+ transitionInfo.to != KeyguardState.GONE && !inLockdown
+ }
+
+ fun notifyKeyguardEnabled(enabled: Boolean) {
+ repository.setKeyguardEnabled(enabled)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index 8ba09bd..fb65a6d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -176,7 +176,8 @@
if (!returningToGoneAfterCancellation) {
// By default, apply the lockscreen visibility of the current state.
- KeyguardState.lockscreenVisibleInState(currentState)
+ deviceEntryInteractor.get().isLockscreenEnabled() &&
+ KeyguardState.lockscreenVisibleInState(currentState)
} else {
// If we're transitioning to GONE after a prior canceled transition from
// GONE, then this is the camera launch transition from an asleep state back
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
index fed93f0..72fb218 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
@@ -157,7 +157,6 @@
viewController,
backgroundDispatcher,
mainDispatcher,
- mediaFlags,
isSongUpdated
)
@@ -414,7 +413,6 @@
viewController: MediaViewController,
backgroundDispatcher: CoroutineDispatcher,
mainDispatcher: CoroutineDispatcher,
- mediaFlags: MediaFlags,
updateBackground: Boolean,
) {
val traceCookie = viewHolder.hashCode()
@@ -424,13 +422,8 @@
viewController.isArtworkBound = false
}
// Capture width & height from views in foreground for artwork scaling in background
- var width = viewHolder.albumView.measuredWidth
- var height = viewHolder.albumView.measuredHeight
- if (mediaFlags.isSceneContainerEnabled() && (width <= 0 || height <= 0)) {
- // TODO(b/312714128): ensure we have a valid size before setting background
- width = viewController.widthInSceneContainerPx
- height = viewController.heightInSceneContainerPx
- }
+ val width = viewController.widthInSceneContainerPx
+ val height = viewController.heightInSceneContainerPx
withContext(backgroundDispatcher) {
val artwork =
if (viewModel.shouldAddGradient) {
@@ -449,6 +442,11 @@
val colorSchemeChanged =
viewController.colorSchemeTransition.updateColorScheme(viewModel.colorScheme)
val albumView = viewHolder.albumView
+
+ // Set up width of album view constraint.
+ viewController.expandedLayout.getConstraint(albumView.id).layout.mWidth = width
+ viewController.collapsedLayout.getConstraint(albumView.id).layout.mWidth = width
+
albumView.setPadding(0, 0, 0, 0)
if (
updateBackground ||
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionCaptureTarget.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionCaptureTarget.kt
index a618490..de56c84 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionCaptureTarget.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionCaptureTarget.kt
@@ -21,15 +21,17 @@
import android.os.Parcelable
/**
- * Class that represents an area that should be captured. Currently it has only a launch cookie that
- * represents a task but we potentially could add more identifiers e.g. for a pair of tasks.
+ * Class that represents an area that should be captured. Currently it has only a launch cookie and
+ * id that represents a task but we potentially could add more identifiers e.g. for a pair of tasks.
*/
-data class MediaProjectionCaptureTarget(val launchCookie: LaunchCookie?) : Parcelable {
+data class MediaProjectionCaptureTarget(val launchCookie: LaunchCookie?, val taskId: Int) :
+ Parcelable {
- constructor(parcel: Parcel) : this(LaunchCookie.readFromParcel(parcel))
+ constructor(parcel: Parcel) : this(LaunchCookie.readFromParcel(parcel), parcel.readInt())
override fun writeToParcel(dest: Parcel, flags: Int) {
LaunchCookie.writeToParcel(launchCookie, dest)
+ dest.writeInt(taskId)
}
override fun describeContents(): Int = 0
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
copy to packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt
index 252945f..3489459 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionModule.kt
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.pipeline.dagger
+package com.android.systemui.mediaprojection
-import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
-import javax.inject.Qualifier
+import com.android.systemui.mediaprojection.data.repository.MediaProjectionManagerRepository
+import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
+import dagger.Binds
+import dagger.Module
-/** Detailed [DeviceBasedSatelliteRepository] logs */
-@Qualifier
-@MustBeDocumented
-@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
-annotation class OemSatelliteInputLog
+@Module
+interface MediaProjectionModule {
+ @Binds fun mediaRepository(impl: MediaProjectionManagerRepository): MediaProjectionRepository
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
index 4685c5a..d6affd2 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
@@ -174,7 +174,7 @@
// is created and ready to be captured.
val activityStarted =
activityLauncher.startActivityAsUser(intent, userHandle, activityOptions.toBundle()) {
- returnSelectedApp(launchCookie)
+ returnSelectedApp(launchCookie, taskId = -1)
}
// Rely on the ActivityManager to pop up a dialog regarding app suspension
@@ -232,7 +232,7 @@
}
}
- override fun returnSelectedApp(launchCookie: LaunchCookie) {
+ override fun returnSelectedApp(launchCookie: LaunchCookie, taskId: Int) {
taskSelected = true
if (intent.hasExtra(EXTRA_CAPTURE_REGION_RESULT_RECEIVER)) {
// The client requested to return the result in the result receiver instead of
@@ -242,7 +242,7 @@
EXTRA_CAPTURE_REGION_RESULT_RECEIVER,
ResultReceiver::class.java
) as ResultReceiver
- val captureRegion = MediaProjectionCaptureTarget(launchCookie)
+ val captureRegion = MediaProjectionCaptureTarget(launchCookie, taskId)
val data = Bundle().apply { putParcelable(KEY_CAPTURE_TARGET, captureRegion) }
resultReceiver.send(RESULT_OK, data)
// TODO(b/279175710): Ensure consent result is always set here. Skipping this for now
@@ -255,6 +255,7 @@
val projection = IMediaProjection.Stub.asInterface(mediaProjectionBinder)
projection.setLaunchCookie(launchCookie)
+ projection.setTaskId(taskId)
val intent = Intent()
intent.putExtra(EXTRA_MEDIA_PROJECTION, projection.asBinder())
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
index f08bc17..9b1ca1e 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
@@ -65,7 +65,7 @@
subcomponents = [MediaProjectionAppSelectorComponent::class],
includes = [MediaProjectionDevicePolicyModule::class]
)
-interface MediaProjectionModule {
+interface MediaProjectionActivitiesModule {
@Binds
@IntoMap
@ClassKey(MediaProjectionAppSelectorActivity::class)
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorResultHandler.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorResultHandler.kt
index f204b3e..6857000 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorResultHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorResultHandler.kt
@@ -9,7 +9,10 @@
interface MediaProjectionAppSelectorResultHandler {
/**
* Return selected app to the original caller of the media projection app picker.
- * @param launchCookie launch cookie of the launched activity of the target app
+ * @param launchCookie launch cookie of the launched activity of the target app, always set
+ * regardless of launching a new task or a recent task
+ * @param taskId id of the launched task of the target app, only set to a positive int when
+ * launching a recent task, otherwise set to -1 by default
*/
- fun returnSelectedApp(launchCookie: LaunchCookie)
+ fun returnSelectedApp(launchCookie: LaunchCookie, taskId: Int)
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
index 9549ab1..46aa064 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
@@ -144,10 +144,9 @@
activityOptions.launchDisplayId = task.displayId
activityOptions.setLaunchCookie(launchCookie)
- val handleResult: () -> Unit = { resultHandler.returnSelectedApp(launchCookie)}
-
val taskId = task.taskId
val splitBounds = task.splitBounds
+ val handleResult: () -> Unit = { resultHandler.returnSelectedApp(launchCookie, taskId)}
if (pssAppSelectorRecentsSplitScreen() &&
task.isLaunchingInSplitScreen() &&
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/model/MediaProjectionState.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/model/MediaProjectionState.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt
index cfbcaf9..1d5f6f5 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/model/MediaProjectionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/model/MediaProjectionState.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 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,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.mediaprojection.taskswitcher.data.model
+package com.android.systemui.mediaprojection.data.model
import android.app.ActivityManager.RunningTaskInfo
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionManagerRepository.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionManagerRepository.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
index 74d1992..3ce0a1e0 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionManagerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 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,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.mediaprojection.taskswitcher.data.repository
+package com.android.systemui.mediaprojection.data.repository
import android.app.ActivityManager.RunningTaskInfo
import android.media.projection.MediaProjectionInfo
@@ -24,20 +24,21 @@
import android.view.ContentRecordingSession
import android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
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.mediaprojection.MediaProjectionServiceHelper
-import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.taskswitcher.data.repository.TasksRepository
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -88,7 +89,11 @@
mediaProjectionManager.addCallback(callback, handler)
awaitClose { mediaProjectionManager.removeCallback(callback) }
}
- .shareIn(scope = applicationScope, started = SharingStarted.Lazily, replay = 1)
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Lazily,
+ initialValue = MediaProjectionState.NotProjecting,
+ )
private suspend fun stateForSession(session: ContentRecordingSession?): MediaProjectionState {
if (session == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionRepository.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionRepository.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
index e495466..21300db 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.mediaprojection.taskswitcher.data.repository
+package com.android.systemui.mediaprojection.data.repository
import android.app.ActivityManager.RunningTaskInfo
-import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import kotlinx.coroutines.flow.Flow
/** Represents a repository to retrieve and change data related to media projection. */
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/MediaProjectionTaskSwitcherModule.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/MediaProjectionTaskSwitcherModule.kt
index 22ad07e..eb38958 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/MediaProjectionTaskSwitcherModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/MediaProjectionTaskSwitcherModule.kt
@@ -17,16 +17,11 @@
package com.android.systemui.mediaprojection.taskswitcher
import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository
-import com.android.systemui.mediaprojection.taskswitcher.data.repository.MediaProjectionManagerRepository
-import com.android.systemui.mediaprojection.taskswitcher.data.repository.MediaProjectionRepository
import com.android.systemui.mediaprojection.taskswitcher.data.repository.TasksRepository
import dagger.Binds
import dagger.Module
@Module
interface MediaProjectionTaskSwitcherModule {
-
- @Binds fun mediaRepository(impl: MediaProjectionManagerRepository): MediaProjectionRepository
-
@Binds fun tasksRepository(impl: ActivityTaskManagerTasksRepository): TasksRepository
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/domain/interactor/TaskSwitchInteractor.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/domain/interactor/TaskSwitchInteractor.kt
index eb9e6a5..c232d4d 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/domain/interactor/TaskSwitchInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/domain/interactor/TaskSwitchInteractor.kt
@@ -21,8 +21,8 @@
import android.content.Intent
import android.util.Log
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
-import com.android.systemui.mediaprojection.taskswitcher.data.repository.MediaProjectionRepository
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
import com.android.systemui.mediaprojection.taskswitcher.data.repository.TasksRepository
import com.android.systemui.mediaprojection.taskswitcher.domain.model.TaskSwitchState
import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 9487085..d0f8412 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.navigationbar.gestural;
+import static android.content.pm.ActivityInfo.CONFIG_FONT_SCALE;
import static android.view.InputDevice.SOURCE_MOUSE;
import static android.view.InputDevice.SOURCE_TOUCHPAD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
@@ -24,10 +25,13 @@
import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadScroll;
import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
+import static java.util.stream.Collectors.joining;
+
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
@@ -47,6 +51,7 @@
import android.os.SystemProperties;
import android.os.Trace;
import android.provider.DeviceConfig;
+import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@@ -102,6 +107,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
@@ -255,7 +261,7 @@
private boolean mIsAttached;
private boolean mIsGestureHandlingEnabled;
- private boolean mIsTrackpadConnected;
+ private final Set<Integer> mTrackpadsConnected = new ArraySet<>();
private boolean mInGestureNavMode;
private boolean mUsingThreeButtonNav;
private boolean mIsEnabled;
@@ -358,16 +364,14 @@
private final InputManager.InputDeviceListener mInputDeviceListener =
new InputManager.InputDeviceListener() {
-
- // Only one trackpad can be connected to a device at a time, since it takes over the
- // only USB port.
- private int mTrackpadDeviceId;
-
@Override
public void onInputDeviceAdded(int deviceId) {
if (isTrackpadDevice(deviceId)) {
- mTrackpadDeviceId = deviceId;
- update(true /* isTrackpadConnected */);
+ boolean wasEmpty = mTrackpadsConnected.isEmpty();
+ mTrackpadsConnected.add(deviceId);
+ if (wasEmpty) {
+ update();
+ }
}
}
@@ -376,18 +380,29 @@
@Override
public void onInputDeviceRemoved(int deviceId) {
- if (mTrackpadDeviceId == deviceId) {
- update(false /* isTrackpadConnected */);
+ mTrackpadsConnected.remove(deviceId);
+ if (mTrackpadsConnected.isEmpty()) {
+ update();
}
}
- private void update(boolean isTrackpadConnected) {
- boolean isPreviouslyTrackpadConnected = mIsTrackpadConnected;
- mIsTrackpadConnected = isTrackpadConnected;
- if (isPreviouslyTrackpadConnected != mIsTrackpadConnected) {
- updateIsEnabled();
- updateCurrentUserResources();
+ private void update() {
+ if (mIsEnabled && !mTrackpadsConnected.isEmpty()) {
+ // Don't reinitialize gesture handling due to trackpad connecting when it's
+ // already set up.
+ return;
}
+ updateIsEnabled();
+ updateCurrentUserResources();
+ }
+
+ private boolean isTrackpadDevice(int deviceId) {
+ InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
+ if (inputDevice == null) {
+ return false;
+ }
+ return inputDevice.getSources() == (InputDevice.SOURCE_MOUSE
+ | InputDevice.SOURCE_TOUCHPAD);
}
};
@@ -566,6 +581,7 @@
mOverviewProxyService.removeCallback(mQuickSwitchListener);
mSysUiState.removeCallback(mSysUiStateCallback);
mInputManager.unregisterInputDeviceListener(mInputDeviceListener);
+ mTrackpadsConnected.clear();
updateIsEnabled();
mUserTracker.removeCallback(mUserChangedCallback);
}
@@ -605,7 +621,7 @@
Trace.beginSection("EdgeBackGestureHandler#updateIsEnabled");
mIsGestureHandlingEnabled = mInGestureNavMode || (mUsingThreeButtonNav
- && mIsTrackpadConnected);
+ && !mTrackpadsConnected.isEmpty());
boolean isEnabled = mIsAttached && mIsGestureHandlingEnabled;
if (isEnabled == mIsEnabled) {
return;
@@ -867,15 +883,6 @@
mDisplaySize.y - insets.bottom);
}
- private boolean isTrackpadDevice(int deviceId) {
- InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
- if (inputDevice == null) {
- return false;
- }
- return inputDevice.getSources() == (InputDevice.SOURCE_MOUSE
- | InputDevice.SOURCE_TOUCHPAD);
- }
-
private boolean desktopExcludeRegionContains(int x, int y) {
return mDesktopModeExcludeRegion.contains(x, y);
}
@@ -1175,6 +1182,10 @@
// TODO(b/332635834): Disable this logging once b/332635834 is fixed.
Log.i(DEBUG_MISSING_GESTURE_TAG, "Config changed: newConfig=" + newConfig
+ " lastReportedConfig=" + mLastReportedConfig);
+ final int diff = newConfig.diff(mLastReportedConfig);
+ if ((diff & CONFIG_FONT_SCALE) != 0 || (diff & ActivityInfo.CONFIG_DENSITY) != 0) {
+ updateCurrentUserResources();
+ }
mLastReportedConfig.updateFrom(newConfig);
updateDisplaySize();
}
@@ -1251,7 +1262,8 @@
pw.println(" mPredictionLog=" + String.join("\n", mPredictionLog));
pw.println(" mGestureLogInsideInsets=" + String.join("\n", mGestureLogInsideInsets));
pw.println(" mGestureLogOutsideInsets=" + String.join("\n", mGestureLogOutsideInsets));
- pw.println(" mIsTrackpadConnected=" + mIsTrackpadConnected);
+ pw.println(" mTrackpadsConnected=" + mTrackpadsConnected.stream().map(
+ String::valueOf).collect(joining()));
pw.println(" mUsingThreeButtonNav=" + mUsingThreeButtonNav);
pw.println(" mEdgeBackPlugin=" + mEdgeBackPlugin);
if (mEdgeBackPlugin != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index b34b370..e77bd03 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -485,6 +485,11 @@
}
@Override
+ public int getMinRows() {
+ return mMinRows;
+ }
+
+ @Override
public boolean setMaxColumns(int maxColumns) {
mMaxColumns = maxColumns;
boolean changed = false;
@@ -497,6 +502,11 @@
return changed;
}
+ @Override
+ public int getMaxColumns() {
+ return mMaxColumns;
+ }
+
/**
* Set the amount of excess space that we gave this view compared to the actual available
* height. This is because this view is in a scrollview.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 00757b7..9c8c17b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -42,6 +42,7 @@
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.settings.brightness.BrightnessSliderController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -441,7 +442,7 @@
}
private boolean needsDynamicRowsAndColumns() {
- return true;
+ return !SceneContainerFlag.isEnabled();
}
private void switchAllContentToParent(ViewGroup parent, QSTileLayout newLayout) {
@@ -634,8 +635,7 @@
switchAllContentToParent(newParent, mTileLayout);
reAttachMediaHost(mediaHostView, horizontal);
if (needsDynamicRowsAndColumns()) {
- mTileLayout.setMinRows(horizontal ? 2 : 1);
- mTileLayout.setMaxColumns(horizontal ? 2 : 4);
+ setColumnRowLayout(horizontal);
}
updateMargins(mediaHostView);
if (mHorizontalLinearLayout != null) {
@@ -644,6 +644,11 @@
}
}
+ void setColumnRowLayout(boolean withMedia) {
+ mTileLayout.setMinRows(withMedia ? 2 : 1);
+ mTileLayout.setMaxColumns(withMedia ? 2 : 4);
+ }
+
private void updateMargins(ViewGroup mediaHostView) {
updateMediaHostContentMargins(mediaHostView);
updateHorizontalLinearLayoutMargins();
@@ -736,6 +741,8 @@
return false;
}
+ int getMinRows();
+
/**
* Sets the max number of columns to show
*
@@ -747,6 +754,8 @@
return false;
}
+ int getMaxColumns();
+
/**
* Sets the expansion value and proposedTranslation to panel.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index e24caf1..f76183e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -30,6 +30,7 @@
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.haptics.qs.QSLongPressEffect;
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor;
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager;
import com.android.systemui.media.controls.ui.view.MediaHost;
import com.android.systemui.media.controls.ui.view.MediaHostState;
@@ -46,10 +47,13 @@
import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.tuner.TunerService;
+import kotlinx.coroutines.flow.StateFlow;
+
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
+
/**
* Controller for {@link QSPanel}.
*/
@@ -72,6 +76,8 @@
private final BrightnessSliderController.Factory mBrightnessSliderControllerFactory;
private final BrightnessController.Factory mBrightnessControllerFactory;
+ protected final MediaCarouselInteractor mMediaCarouselInteractor;
+
private View.OnTouchListener mTileLayoutTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@@ -94,7 +100,8 @@
FalsingManager falsingManager,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
SplitShadeStateController splitShadeStateController,
- Provider<QSLongPressEffect> longPRessEffectProvider) {
+ Provider<QSLongPressEffect> longPRessEffectProvider,
+ MediaCarouselInteractor mediaCarouselInteractor) {
super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost,
metricsLogger, uiEventLogger, qsLogger, dumpManager, splitShadeStateController,
longPRessEffectProvider);
@@ -113,6 +120,7 @@
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mLastDensity = view.getResources().getConfiguration().densityDpi;
mSceneContainerEnabled = SceneContainerFlag.isEnabled();
+ mMediaCarouselInteractor = mediaCarouselInteractor;
}
@Override
@@ -126,6 +134,11 @@
}
@Override
+ StateFlow<Boolean> getMediaVisibleFlow() {
+ return mMediaCarouselInteractor.getHasAnyMediaOrRecommendation();
+ }
+
+ @Override
protected void onViewAttached() {
super.onViewAttached();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 583cfb9..3b5cc61 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -41,13 +41,17 @@
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileViewImpl;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.animation.DisappearParameters;
+import com.android.systemui.util.kotlin.JavaAdapterKt;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
+import kotlinx.coroutines.flow.StateFlow;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
@@ -58,6 +62,7 @@
import javax.inject.Provider;
+
/**
* Controller for QSPanel views.
*
@@ -93,6 +98,15 @@
private final Provider<QSLongPressEffect> mLongPressEffectProvider;
+ private boolean mDestroyed = false;
+
+ private boolean mMediaVisibleFromInteractor;
+
+ private final Consumer<Boolean> mMediaOrRecommendationVisibleConsumer = mediaVisible -> {
+ mMediaVisibleFromInteractor = mediaVisible;
+ setLayoutForMediaInScene();
+ };
+
@VisibleForTesting
protected final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
new QSPanel.OnConfigurationChangedListener() {
@@ -115,7 +129,11 @@
/* newScreenLayout= */ mLastScreenLayout,
/* containerName= */ mView.getDumpableTag());
- switchTileLayoutIfNeeded();
+ if (SceneContainerFlag.isEnabled()) {
+ setLayoutForMediaInScene();
+ } else {
+ switchTileLayoutIfNeeded();
+ }
onConfigurationChanged();
if (previousSplitShadeState != mShouldUseSplitNotificationShade) {
onSplitShadeChanged(mShouldUseSplitNotificationShade);
@@ -173,6 +191,9 @@
mView.initialize(mQSLogger, mUsingMediaPlayer);
mQSLogger.logAllTilesChangeListening(mView.isListening(), mView.getDumpableTag(), "");
mHost.addCallback(mQSHostCallback);
+ if (SceneContainerFlag.isEnabled()) {
+ registerForMediaInteractorChanges();
+ }
}
/**
@@ -192,7 +213,7 @@
// will remove the attach listener. We don't need to do that, because once this object is
// detached from the graph, it will be gc.
mHost.removeCallback(mQSHostCallback);
-
+ mDestroyed = true;
for (TileRecord record : mRecords) {
record.tile.removeCallback(record.callback);
mView.removeTile(record);
@@ -207,17 +228,32 @@
mQsTileRevealController.setExpansion(mRevealExpansion);
}
- mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener);
+ if (!SceneContainerFlag.isEnabled()) {
+ mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener);
+ }
mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
setTiles();
mLastOrientation = getResources().getConfiguration().orientation;
mLastScreenLayout = getResources().getConfiguration().screenLayout;
mQSLogger.logOnViewAttached(mLastOrientation, mView.getDumpableTag());
+ if (SceneContainerFlag.isEnabled()) {
+ setLayoutForMediaInScene();
+ }
switchTileLayout(true);
mDumpManager.registerDumpable(mView.getDumpableTag(), this);
}
+ private void registerForMediaInteractorChanges() {
+ JavaAdapterKt.collectFlow(
+ mView,
+ getMediaVisibleFlow(),
+ mMediaOrRecommendationVisibleConsumer
+ );
+ }
+
+ abstract StateFlow<Boolean> getMediaVisibleFlow();
+
@Override
protected void onViewDetached() {
mQSLogger.logOnViewDetached(mLastOrientation, mView.getDumpableTag());
@@ -242,6 +278,7 @@
/** */
public void setTiles(Collection<QSTile> tiles, boolean collapsedView) {
+ if (mDestroyed) return;
// TODO(b/168904199): move this logic into QSPanelController.
if (!collapsedView && mQsTileRevealController != null) {
mQsTileRevealController.updateRevealedTiles(tiles);
@@ -433,6 +470,11 @@
return false;
}
+ void setLayoutForMediaInScene() {
+ boolean withMedia = shouldUseHorizontalInScene();
+ mView.setColumnRowLayout(withMedia);
+ }
+
/**
* Update the way the media disappears based on if we're using the horizontal layout
*/
@@ -473,6 +515,16 @@
== Configuration.SCREENLAYOUT_LONG_YES;
}
+ boolean shouldUseHorizontalInScene() {
+ if (mShouldUseSplitNotificationShade) {
+ return false;
+ }
+ return mMediaVisibleFromInteractor
+ && mLastOrientation == Configuration.ORIENTATION_LANDSCAPE
+ && (mLastScreenLayout & Configuration.SCREENLAYOUT_LONG_MASK)
+ == Configuration.SCREENLAYOUT_LONG_YES;
+ }
+
private void logTiles() {
for (int i = 0; i < mRecords.size(); i++) {
QSTile tile = mRecords.get(i).tile;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index 6cda740..f207b1d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -26,6 +26,7 @@
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.haptics.qs.QSLongPressEffect;
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor;
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager;
import com.android.systemui.media.controls.ui.view.MediaHost;
import com.android.systemui.plugins.qs.QSTile;
@@ -36,6 +37,8 @@
import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.leak.RotationUtils;
+import kotlinx.coroutines.flow.StateFlow;
+
import java.util.ArrayList;
import java.util.List;
@@ -43,12 +46,15 @@
import javax.inject.Named;
import javax.inject.Provider;
+
/** Controller for {@link QuickQSPanel}. */
@QSScope
public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel> {
private final Provider<Boolean> mUsingCollapsedLandscapeMediaProvider;
+ private final MediaCarouselInteractor mMediaCarouselInteractor;
+
@Inject
QuickQSPanelController(QuickQSPanel view, QSHost qsHost,
QSCustomizerController qsCustomizerController,
@@ -58,12 +64,14 @@
Provider<Boolean> usingCollapsedLandscapeMediaProvider,
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
DumpManager dumpManager, SplitShadeStateController splitShadeStateController,
- Provider<QSLongPressEffect> longPressEffectProvider
+ Provider<QSLongPressEffect> longPressEffectProvider,
+ MediaCarouselInteractor mediaCarouselInteractor
) {
super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
uiEventLogger, qsLogger, dumpManager, splitShadeStateController,
longPressEffectProvider);
mUsingCollapsedLandscapeMediaProvider = usingCollapsedLandscapeMediaProvider;
+ mMediaCarouselInteractor = mediaCarouselInteractor;
}
@Override
@@ -74,6 +82,11 @@
mMediaHost.init(MediaHierarchyManager.LOCATION_QQS);
}
+ @Override
+ StateFlow<Boolean> getMediaVisibleFlow() {
+ return mMediaCarouselInteractor.getHasActiveMediaOrRecommendation();
+ }
+
private void updateMediaExpansion() {
int rotation = getRotation();
boolean isLandscape = rotation == RotationUtils.ROTATION_LANDSCAPE
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index dcb9288..ef44e5f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -12,6 +12,7 @@
import android.widget.TextView;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.FontSizeUtils;
@@ -97,12 +98,24 @@
return false;
}
+ @VisibleForTesting
+ @Override
+ public int getMinRows() {
+ return mMinRows;
+ }
+
@Override
public boolean setMaxColumns(int maxColumns) {
mMaxColumns = maxColumns;
return updateColumns();
}
+ @VisibleForTesting
+ @Override
+ public int getMaxColumns() {
+ return mMaxColumns;
+ }
+
public void addTile(TileRecord tile) {
mRecords.add(tile);
tile.tile.setListening(this, mListening);
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 d161c6b..7b67993 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
@@ -28,6 +28,7 @@
import com.android.systemui.qs.panels.domain.interactor.NoopGridConsistencyInteractor
import com.android.systemui.qs.panels.shared.model.GridConsistencyLog
import com.android.systemui.qs.panels.shared.model.GridLayoutType
+import com.android.systemui.qs.panels.shared.model.IconLabelVisibilityLog
import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
import com.android.systemui.qs.panels.shared.model.PartitionedGridLayoutType
import com.android.systemui.qs.panels.shared.model.StretchedGridLayoutType
@@ -35,6 +36,12 @@
import com.android.systemui.qs.panels.ui.compose.InfiniteGridLayout
import com.android.systemui.qs.panels.ui.compose.PartitionedGridLayout
import com.android.systemui.qs.panels.ui.compose.StretchedGridLayout
+import com.android.systemui.qs.panels.ui.viewmodel.IconLabelVisibilityViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.IconLabelVisibilityViewModelImpl
+import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModelImpl
+import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModelImpl
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -53,6 +60,15 @@
impl: NoopGridConsistencyInteractor
): GridTypeConsistencyInteractor
+ @Binds fun bindIconTilesViewModel(impl: IconTilesViewModelImpl): IconTilesViewModel
+
+ @Binds fun bindGridSizeViewModel(impl: InfiniteGridSizeViewModelImpl): InfiniteGridSizeViewModel
+
+ @Binds
+ fun bindIconLabelVisibilityViewModel(
+ impl: IconLabelVisibilityViewModelImpl
+ ): IconLabelVisibilityViewModel
+
@Binds @Named("Default") fun bindDefaultGridLayout(impl: PartitionedGridLayout): GridLayout
companion object {
@@ -64,6 +80,13 @@
}
@Provides
+ @SysUISingleton
+ @IconLabelVisibilityLog
+ fun providesIconTileLabelVisibilityLog(factory: LogBufferFactory): LogBuffer {
+ return factory.create("IconLabelVisibilityLog", 50)
+ }
+
+ @Provides
@IntoSet
fun provideGridLayout(gridLayout: InfiniteGridLayout): Pair<GridLayoutType, GridLayout> {
return Pair(InfiniteGridLayoutType, gridLayout)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconLabelVisibilityRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconLabelVisibilityRepository.kt
new file mode 100644
index 0000000..686e5f4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconLabelVisibilityRepository.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.qs.panels.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** Repository for whether to show the labels of icon tiles. */
+@SysUISingleton
+class IconLabelVisibilityRepository @Inject constructor() {
+ // TODO(b/341735914): Persist and back up showLabels
+ private val _showLabels = MutableStateFlow(false)
+ val showLabels: StateFlow<Boolean> = _showLabels.asStateFlow()
+
+ fun setShowLabels(showLabels: Boolean) {
+ _showLabels.value = showLabels
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt
new file mode 100644
index 0000000..a871531
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractor.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.qs.panels.data.repository.IconLabelVisibilityRepository
+import com.android.systemui.qs.panels.shared.model.IconLabelVisibilityLog
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
+
+@SysUISingleton
+class IconLabelVisibilityInteractor
+@Inject
+constructor(
+ private val repo: IconLabelVisibilityRepository,
+ @IconLabelVisibilityLog private val logBuffer: LogBuffer,
+ @Application scope: CoroutineScope,
+) {
+ val showLabels: StateFlow<Boolean> =
+ repo.showLabels
+ .onEach { logChange(it) }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), repo.showLabels.value)
+
+ fun setShowLabels(showLabels: Boolean) {
+ repo.setShowLabels(showLabels)
+ }
+
+ private fun logChange(showLabels: Boolean) {
+ logBuffer.log(
+ LOG_BUFFER_ICON_TILE_LABEL_VISIBILITY_CHANGE_TAG,
+ LogLevel.DEBUG,
+ { bool1 = showLabels },
+ { "Icon tile label visibility changed: $bool1" }
+ )
+ }
+
+ private companion object {
+ const val LOG_BUFFER_ICON_TILE_LABEL_VISIBILITY_CHANGE_TAG = "IconLabelVisibilityChange"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/IconLabelVisibilityLog.kt
similarity index 69%
copy from packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
copy to packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/IconLabelVisibilityLog.kt
index 252945f..c92234c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/IconLabelVisibilityLog.kt
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.pipeline.dagger
+package com.android.systemui.qs.panels.shared.model
-import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
import javax.inject.Qualifier
-/** Detailed [DeviceBasedSatelliteRepository] logs */
@Qualifier
@MustBeDocumented
-@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
-annotation class OemSatelliteInputLog
+@Retention(AnnotationRetention.RUNTIME)
+annotation class IconLabelVisibilityLog()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
index f5ee720..4aeaa7d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
@@ -26,9 +26,9 @@
import androidx.compose.ui.res.dimensionResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.domain.interactor.IconTilesInteractor
-import com.android.systemui.qs.panels.domain.interactor.InfiniteGridSizeInteractor
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.res.R
@@ -38,8 +38,8 @@
class InfiniteGridLayout
@Inject
constructor(
- private val iconTilesInteractor: IconTilesInteractor,
- private val gridSizeInteractor: InfiniteGridSizeInteractor
+ private val iconTilesViewModel: IconTilesViewModel,
+ private val gridSizeViewModel: InfiniteGridSizeViewModel,
) : GridLayout {
@Composable
@@ -52,8 +52,8 @@
tiles.forEach { it.startListening(token) }
onDispose { tiles.forEach { it.stopListening(token) } }
}
- val iconTilesSpecs by iconTilesInteractor.iconTilesSpecs.collectAsStateWithLifecycle()
- val columns by gridSizeInteractor.columns.collectAsStateWithLifecycle()
+ val iconTilesSpecs by iconTilesViewModel.iconTilesSpecs.collectAsStateWithLifecycle()
+ val columns by gridSizeViewModel.columns.collectAsStateWithLifecycle()
TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) {
items(
@@ -68,9 +68,9 @@
}
) { index ->
Tile(
- tiles[index],
- iconTilesSpecs.contains(tiles[index].spec),
- Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
+ tile = tiles[index],
+ iconOnly = iconTilesSpecs.contains(tiles[index].spec),
+ modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
)
}
}
@@ -83,8 +83,8 @@
onAddTile: (TileSpec, Int) -> Unit,
onRemoveTile: (TileSpec) -> Unit,
) {
- val iconOnlySpecs by iconTilesInteractor.iconTilesSpecs.collectAsStateWithLifecycle()
- val columns by gridSizeInteractor.columns.collectAsStateWithLifecycle()
+ val iconOnlySpecs by iconTilesViewModel.iconTilesSpecs.collectAsStateWithLifecycle()
+ val columns by gridSizeViewModel.columns.collectAsStateWithLifecycle()
DefaultEditTileGrid(
tiles = tiles,
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 8d0b386..708ef0d 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
@@ -20,6 +20,7 @@
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -32,6 +33,8 @@
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
@@ -39,14 +42,14 @@
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.modifiers.background
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.domain.interactor.IconTilesInteractor
-import com.android.systemui.qs.panels.domain.interactor.InfiniteGridSizeInteractor
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.PartitionedGridViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -54,12 +57,8 @@
import javax.inject.Inject
@SysUISingleton
-class PartitionedGridLayout
-@Inject
-constructor(
- private val iconTilesInteractor: IconTilesInteractor,
- private val gridSizeInteractor: InfiniteGridSizeInteractor,
-) : GridLayout {
+class PartitionedGridLayout @Inject constructor(private val viewModel: PartitionedGridViewModel) :
+ GridLayout {
@Composable
override fun TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
DisposableEffect(tiles) {
@@ -67,9 +66,11 @@
tiles.forEach { it.startListening(token) }
onDispose { tiles.forEach { it.stopListening(token) } }
}
- val iconTilesSpecs by iconTilesInteractor.iconTilesSpecs.collectAsStateWithLifecycle()
- val columns by gridSizeInteractor.columns.collectAsStateWithLifecycle()
- val tileHeight = dimensionResource(id = R.dimen.qs_tile_height)
+ val iconTilesSpecs by viewModel.iconTilesSpecs.collectAsStateWithLifecycle()
+ val columns by viewModel.columns.collectAsStateWithLifecycle()
+ val showLabels by viewModel.showLabels.collectAsStateWithLifecycle()
+ val largeTileHeight = tileHeight()
+ val iconTileHeight = tileHeight(showLabels)
val (smallTiles, largeTiles) = tiles.partition { iconTilesSpecs.contains(it.spec) }
TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) {
@@ -78,7 +79,7 @@
Tile(
tile = largeTiles[index],
iconOnly = false,
- modifier = Modifier.height(tileHeight)
+ modifier = Modifier.height(largeTileHeight)
)
}
fillUpRow(nTiles = largeTiles.size, columns = columns / 2)
@@ -88,7 +89,8 @@
Tile(
tile = smallTiles[index],
iconOnly = true,
- modifier = Modifier.height(tileHeight)
+ showLabels = showLabels,
+ modifier = Modifier.height(iconTileHeight)
)
}
}
@@ -101,8 +103,9 @@
onAddTile: (TileSpec, Int) -> Unit,
onRemoveTile: (TileSpec) -> Unit
) {
- val iconOnlySpecs by iconTilesInteractor.iconTilesSpecs.collectAsStateWithLifecycle()
- val columns by gridSizeInteractor.columns.collectAsStateWithLifecycle()
+ val iconOnlySpecs by viewModel.iconTilesSpecs.collectAsStateWithLifecycle()
+ val columns by viewModel.columns.collectAsStateWithLifecycle()
+ val showLabels by viewModel.showLabels.collectAsStateWithLifecycle()
val (currentTiles, otherTiles) = tiles.partition { it.isCurrent }
val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
@@ -110,27 +113,56 @@
}
val isIconOnly: (TileSpec) -> Boolean =
remember(iconOnlySpecs) { { tileSpec: TileSpec -> tileSpec in iconOnlySpecs } }
- val tileHeight = dimensionResource(id = R.dimen.qs_tile_height)
+ val largeTileHeight = tileHeight()
+ val iconTileHeight = tileHeight(showLabels)
val tilePadding = dimensionResource(R.dimen.qs_tile_margin_vertical)
Column(
verticalArrangement = Arrangement.spacedBy(tilePadding),
modifier = modifier.fillMaxSize().verticalScroll(rememberScrollState())
) {
+ Row(
+ modifier =
+ Modifier.background(
+ color = MaterialTheme.colorScheme.surfaceVariant,
+ alpha = { 1f },
+ shape = RoundedCornerShape(dimensionResource(R.dimen.qs_corner_radius))
+ )
+ .padding(tilePadding)
+ ) {
+ Column(Modifier.padding(start = tilePadding)) {
+ Text(
+ text = "Show text labels",
+ color = MaterialTheme.colorScheme.onBackground,
+ fontWeight = FontWeight.Bold
+ )
+ Text(
+ text = "Display names under each tile",
+ color = MaterialTheme.colorScheme.onBackground
+ )
+ }
+ Spacer(modifier = Modifier.weight(1f))
+ Switch(checked = showLabels, onCheckedChange = { viewModel.setShowLabels(it) })
+ }
+
CurrentTiles(
tiles = currentTiles,
- tileHeight = tileHeight,
+ largeTileHeight = largeTileHeight,
+ iconTileHeight = iconTileHeight,
tilePadding = tilePadding,
onRemoveTile = onRemoveTile,
isIconOnly = isIconOnly,
columns = columns,
+ showLabels = showLabels,
)
AvailableTiles(
tiles = otherTiles,
- tileHeight = tileHeight,
+ largeTileHeight = largeTileHeight,
+ iconTileHeight = iconTileHeight,
tilePadding = tilePadding,
addTileToEnd = addTileToEnd,
isIconOnly = isIconOnly,
+ showLabels = showLabels,
columns = columns,
)
}
@@ -139,23 +171,31 @@
@Composable
private fun CurrentTiles(
tiles: List<EditTileViewModel>,
- tileHeight: Dp,
+ largeTileHeight: Dp,
+ iconTileHeight: Dp,
tilePadding: Dp,
onRemoveTile: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
+ showLabels: Boolean,
columns: Int,
) {
val (smallTiles, largeTiles) = tiles.partition { isIconOnly(it.tileSpec) }
- val largeGridHeight = gridHeight(largeTiles.size, tileHeight, columns / 2, tilePadding)
- val smallGridHeight = gridHeight(smallTiles.size, tileHeight, columns, tilePadding)
+ val largeGridHeight = gridHeight(largeTiles.size, largeTileHeight, columns / 2, tilePadding)
+ val smallGridHeight = gridHeight(smallTiles.size, iconTileHeight, columns, tilePadding)
CurrentTilesContainer {
TileLazyGrid(
columns = GridCells.Fixed(columns),
modifier = Modifier.height(largeGridHeight),
) {
- editTiles(largeTiles, ClickAction.REMOVE, onRemoveTile, { false }, true)
+ editTiles(
+ largeTiles,
+ ClickAction.REMOVE,
+ onRemoveTile,
+ { false },
+ indicatePosition = true
+ )
}
}
CurrentTilesContainer {
@@ -163,7 +203,14 @@
columns = GridCells.Fixed(columns),
modifier = Modifier.height(smallGridHeight),
) {
- editTiles(smallTiles, ClickAction.REMOVE, onRemoveTile, { true }, true)
+ editTiles(
+ smallTiles,
+ ClickAction.REMOVE,
+ onRemoveTile,
+ { true },
+ showLabels = showLabels,
+ indicatePosition = true
+ )
}
}
}
@@ -171,19 +218,21 @@
@Composable
private fun AvailableTiles(
tiles: List<EditTileViewModel>,
- tileHeight: Dp,
+ largeTileHeight: Dp,
+ iconTileHeight: Dp,
tilePadding: Dp,
addTileToEnd: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
+ showLabels: Boolean,
columns: Int,
) {
val (tilesStock, tilesCustom) = tiles.partition { it.appName == null }
val (smallTiles, largeTiles) = tilesStock.partition { isIconOnly(it.tileSpec) }
- val largeGridHeight = gridHeight(largeTiles.size, tileHeight, columns / 2, tilePadding)
- val smallGridHeight = gridHeight(smallTiles.size, tileHeight, columns, tilePadding)
+ val largeGridHeight = gridHeight(largeTiles.size, largeTileHeight, columns / 2, tilePadding)
+ val smallGridHeight = gridHeight(smallTiles.size, iconTileHeight, columns, tilePadding)
val largeGridHeightCustom =
- gridHeight(tilesCustom.size, tileHeight, columns / 2, tilePadding)
+ gridHeight(tilesCustom.size, largeTileHeight, columns / 2, tilePadding)
// Add up the height of all three grids and add padding in between
val gridHeight =
@@ -199,7 +248,13 @@
fillUpRow(nTiles = largeTiles.size, columns = columns / 2)
// Small tiles
- editTiles(smallTiles, ClickAction.ADD, addTileToEnd, isIconOnly)
+ editTiles(
+ smallTiles,
+ ClickAction.ADD,
+ addTileToEnd,
+ isIconOnly,
+ showLabels = showLabels
+ )
fillUpRow(nTiles = smallTiles.size, columns = columns)
// Custom tiles, all large
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
index ddd97c2..70d629f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
@@ -27,11 +27,11 @@
import androidx.compose.ui.res.dimensionResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.domain.interactor.IconTilesInteractor
-import com.android.systemui.qs.panels.domain.interactor.InfiniteGridSizeInteractor
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.TileRow
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.res.R
@@ -41,8 +41,8 @@
class StretchedGridLayout
@Inject
constructor(
- private val iconTilesInteractor: IconTilesInteractor,
- private val gridSizeInteractor: InfiniteGridSizeInteractor,
+ private val iconTilesViewModel: IconTilesViewModel,
+ private val gridSizeViewModel: InfiniteGridSizeViewModel,
) : GridLayout {
@Composable
@@ -60,7 +60,7 @@
// Icon [3 | 4]
// Large [6 | 8]
val columns = 12
- val iconTilesSpecs by iconTilesInteractor.iconTilesSpecs.collectAsStateWithLifecycle()
+ val iconTilesSpecs by iconTilesViewModel.iconTilesSpecs.collectAsStateWithLifecycle()
val stretchedTiles =
remember(tiles) {
val sizedTiles =
@@ -80,9 +80,9 @@
TileLazyGrid(columns = GridCells.Fixed(columns), modifier = modifier) {
items(stretchedTiles.size, span = { GridItemSpan(stretchedTiles[it].width) }) { index ->
Tile(
- stretchedTiles[index].tile,
- iconTilesSpecs.contains(stretchedTiles[index].tile.spec),
- Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
+ tile = stretchedTiles[index].tile,
+ iconOnly = iconTilesSpecs.contains(stretchedTiles[index].tile.spec),
+ modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
)
}
}
@@ -95,8 +95,8 @@
onAddTile: (TileSpec, Int) -> Unit,
onRemoveTile: (TileSpec) -> Unit
) {
- val iconOnlySpecs by iconTilesInteractor.iconTilesSpecs.collectAsStateWithLifecycle()
- val columns by gridSizeInteractor.columns.collectAsStateWithLifecycle()
+ val iconOnlySpecs by iconTilesViewModel.iconTilesSpecs.collectAsStateWithLifecycle()
+ val columns by gridSizeViewModel.columns.collectAsStateWithLifecycle()
DefaultEditTileGrid(
tiles = tiles,
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 e8c65a5..a6838c0 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
@@ -69,6 +69,9 @@
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.Expandable
@@ -98,6 +101,7 @@
fun Tile(
tile: TileViewModel,
iconOnly: Boolean,
+ showLabels: Boolean = false,
modifier: Modifier,
) {
val state: TileUiState by
@@ -136,7 +140,8 @@
secondaryLabel = state.secondaryLabel.toString(),
icon = icon,
colors = state.colors,
- iconOnly = iconOnly
+ iconOnly = iconOnly,
+ showLabels = showLabels,
)
}
}
@@ -213,6 +218,7 @@
clickAction: ClickAction,
onClick: (TileSpec) -> Unit,
isIconOnly: (TileSpec) -> Boolean,
+ showLabels: Boolean = false,
indicatePosition: Boolean = false,
) {
items(
@@ -250,10 +256,13 @@
this.stateDescription = stateDescription
}
) {
+ val iconOnly = isIconOnly(viewModel.tileSpec)
+ val tileHeight = tileHeight(iconOnly && showLabels)
EditTile(
tileViewModel = viewModel,
- isIconOnly(viewModel.tileSpec),
- modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
+ iconOnly = iconOnly,
+ showLabels = showLabels,
+ modifier = Modifier.height(tileHeight)
)
if (canClick) {
Badge(clickAction, Modifier.align(Alignment.TopEnd))
@@ -281,6 +290,7 @@
fun EditTile(
tileViewModel: EditTileViewModel,
iconOnly: Boolean,
+ showLabels: Boolean,
modifier: Modifier = Modifier,
) {
val label = tileViewModel.label.load() ?: tileViewModel.tileSpec.spec
@@ -297,6 +307,7 @@
colors = colors,
icon = tileViewModel.icon,
iconOnly = iconOnly,
+ showLabels = showLabels,
animateIconToEnd = true,
)
}
@@ -380,9 +391,26 @@
icon: Icon,
colors: TileColorAttributes,
iconOnly: Boolean,
+ showLabels: Boolean = false,
animateIconToEnd: Boolean = false,
) {
- TileIcon(icon, colorAttr(colors.icon), animateIconToEnd)
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ modifier = Modifier.fillMaxHeight()
+ ) {
+ TileIcon(icon, colorAttr(colors.icon), animateIconToEnd)
+
+ if (iconOnly && showLabels) {
+ Text(
+ label,
+ maxLines = 2,
+ color = colorAttr(colors.label),
+ overflow = TextOverflow.Ellipsis,
+ textAlign = TextAlign.Center,
+ )
+ }
+ }
if (!iconOnly) {
Column(verticalArrangement = Arrangement.Center, modifier = Modifier.fillMaxHeight()) {
@@ -401,3 +429,16 @@
}
}
}
+
+@Composable
+fun tileHeight(iconWithLabel: Boolean = false): Dp {
+ return if (iconWithLabel) {
+ TileDimensions.IconTileWithLabelHeight
+ } else {
+ dimensionResource(id = R.dimen.qs_tile_height)
+ }
+}
+
+private object TileDimensions {
+ val IconTileWithLabelHeight = 100.dp
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModel.kt
new file mode 100644
index 0000000..5d4b8f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModel.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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.domain.interactor.IconLabelVisibilityInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+interface IconLabelVisibilityViewModel {
+ val showLabels: StateFlow<Boolean>
+
+ fun setShowLabels(showLabels: Boolean)
+}
+
+@SysUISingleton
+class IconLabelVisibilityViewModelImpl
+@Inject
+constructor(private val interactor: IconLabelVisibilityInteractor) : IconLabelVisibilityViewModel {
+ override val showLabels: StateFlow<Boolean> = interactor.showLabels
+
+ override fun setShowLabels(showLabels: Boolean) {
+ interactor.setShowLabels(showLabels)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.kt
new file mode 100644
index 0000000..9ad00c8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModel.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.dagger.SysUISingleton
+import com.android.systemui.qs.panels.domain.interactor.IconTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+interface IconTilesViewModel {
+ val iconTilesSpecs: StateFlow<Set<TileSpec>>
+}
+
+@SysUISingleton
+class IconTilesViewModelImpl @Inject constructor(interactor: IconTilesInteractor) :
+ IconTilesViewModel {
+ override val iconTilesSpecs = interactor.iconTilesSpecs
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModel.kt
new file mode 100644
index 0000000..a4ee58f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModel.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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.domain.interactor.InfiniteGridSizeInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+interface InfiniteGridSizeViewModel {
+ val columns: StateFlow<Int>
+}
+
+@SysUISingleton
+class InfiniteGridSizeViewModelImpl @Inject constructor(interactor: InfiniteGridSizeInteractor) :
+ InfiniteGridSizeViewModel {
+ override val columns: StateFlow<Int> = interactor.columns
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModel.kt
new file mode 100644
index 0000000..730cf63
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModel.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.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+@SysUISingleton
+class PartitionedGridViewModel
+@Inject
+constructor(
+ iconTilesViewModel: IconTilesViewModel,
+ gridSizeViewModel: InfiniteGridSizeViewModel,
+ iconLabelVisibilityViewModel: IconLabelVisibilityViewModel,
+) :
+ IconTilesViewModel by iconTilesViewModel,
+ InfiniteGridSizeViewModel by gridSizeViewModel,
+ IconLabelVisibilityViewModel by iconLabelVisibilityViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 56588ff..8887f58 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -677,6 +677,10 @@
mId = id;
}
+ public int getResourceId() {
+ return mId;
+ }
+
@Override
public boolean equals(Object o) {
return o instanceof DrawableIconWithRes && ((DrawableIconWithRes) o).mId == mId;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 76aa146..f218d86 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -16,8 +16,13 @@
package com.android.systemui.qs.tiles;
-import static android.graphics.drawable.Icon.TYPE_URI;
import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT;
+import static android.graphics.drawable.Icon.TYPE_URI;
+import static android.graphics.drawable.Icon.TYPE_URI_ADAPTIVE_BITMAP;
+import static android.graphics.drawable.Icon.TYPE_RESOURCE;
+import static android.graphics.drawable.Icon.TYPE_BITMAP;
+import static android.graphics.drawable.Icon.TYPE_ADAPTIVE_BITMAP;
+import static android.graphics.drawable.Icon.TYPE_DATA;
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_WALLET_APP_CHANGE;
@@ -237,11 +242,21 @@
return;
}
mSelectedCard = cards.get(selectedIndex);
- android.graphics.drawable.Icon cardImageIcon = mSelectedCard.getCardImage();
- if (cardImageIcon.getType() == TYPE_URI) {
- mCardViewDrawable = null;
- } else {
- mCardViewDrawable = mSelectedCard.getCardImage().loadDrawable(mContext);
+ switch (mSelectedCard.getCardImage().getType()) {
+ case TYPE_URI:
+ case TYPE_URI_ADAPTIVE_BITMAP:
+ mCardViewDrawable = null;
+ break;
+ case TYPE_RESOURCE:
+ case TYPE_BITMAP:
+ case TYPE_ADAPTIVE_BITMAP:
+ case TYPE_DATA:
+ mCardViewDrawable = mSelectedCard.getCardImage().loadDrawable(mContext);
+ break;
+ default:
+ Log.e(TAG, "Unknown icon type: " + mSelectedCard.getCardImage().getType());
+ mCardViewDrawable = null;
+ break;
}
refreshState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index b057476..7bc76af 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -118,6 +118,8 @@
public class InternetDialogController implements AccessPointController.AccessPointCallback {
private static final String TAG = "InternetDialogController";
+ private static final String ACTION_NETWORK_PROVIDER_SETTINGS =
+ "android.settings.NETWORK_PROVIDER_SETTINGS";
private static final String ACTION_WIFI_SCANNING_SETTINGS =
"android.settings.WIFI_SCANNING_SETTINGS";
/**
@@ -361,8 +363,7 @@
@VisibleForTesting
protected Intent getSettingsIntent() {
- return new Intent(Settings.ACTION_NETWORK_PROVIDER_SETTINGS).addFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK);
+ return new Intent(ACTION_NETWORK_PROVIDER_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
@Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
index c0fc52e..f088943 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
@@ -18,6 +18,7 @@
import android.content.res.Resources
import android.content.res.Resources.Theme
+import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
@@ -82,7 +83,8 @@
secondaryLabel = resources.getString(R.string.qs_alarm_tile_no_alarm)
}
}
-
+ iconRes = R.drawable.ic_alarm
+ icon = { Icon.Loaded(resources.getDrawable(iconRes!!, theme), null) }
sideViewIcon = QSTileState.SideViewIcon.Chevron
contentDescription = label
supportedActions = setOf(QSTileState.UserAction.CLICK)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt
index 0c08fba..bcf0935 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt
@@ -38,17 +38,10 @@
QSTileState.build(resources, theme, config.uiConfig) {
label = resources.getString(R.string.battery_detail_switch_title)
contentDescription = label
-
- icon = {
- Icon.Loaded(
- resources.getDrawable(
- if (data.isPowerSaving) R.drawable.qs_battery_saver_icon_on
- else R.drawable.qs_battery_saver_icon_off,
- theme
- ),
- null
- )
- }
+ iconRes =
+ if (data.isPowerSaving) R.drawable.qs_battery_saver_icon_on
+ else R.drawable.qs_battery_saver_icon_off
+ icon = { Icon.Loaded(resources.getDrawable(iconRes!!, theme), null) }
sideViewIcon = QSTileState.SideViewIcon.None
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt
index 1efbfd7..cad7c65 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt
@@ -37,6 +37,8 @@
QSTileState.build(resources, theme, config.uiConfig) {
val subtitleArray = resources.getStringArray(R.array.tile_states_color_correction)
+ iconRes = R.drawable.ic_qs_color_correction
+
if (data.isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
secondaryLabel = subtitleArray[2]
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
index 58e7613..d7d6124 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
@@ -37,14 +37,16 @@
override fun map(config: QSTileConfig, data: FlashlightTileModel): QSTileState =
QSTileState.build(resources, theme, config.uiConfig) {
+ iconRes =
+ if (data is FlashlightTileModel.FlashlightAvailable && data.isEnabled) {
+ R.drawable.qs_flashlight_icon_on
+ } else {
+ R.drawable.qs_flashlight_icon_off
+ }
val icon =
Icon.Loaded(
resources.getDrawable(
- if (data is FlashlightTileModel.FlashlightAvailable && data.isEnabled) {
- R.drawable.qs_flashlight_icon_on
- } else {
- R.drawable.qs_flashlight_icon_off
- },
+ iconRes!!,
theme,
),
contentDescription = null
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt
index 26069c7..6b4dda1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt
@@ -36,10 +36,11 @@
override fun map(config: QSTileConfig, data: FontScalingTileModel): QSTileState =
QSTileState.build(resources, theme, config.uiConfig) {
+ iconRes = R.drawable.ic_qs_font_scaling
val icon =
Icon.Loaded(
resources.getDrawable(
- R.drawable.ic_qs_font_scaling,
+ iconRes!!,
theme,
),
contentDescription = null
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
index caae4d2..e543e4b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
@@ -53,6 +53,7 @@
stateDescription = data.stateDescription.loadContentDescription(context)
contentDescription = data.contentDescription.loadContentDescription(context)
+ iconRes = data.iconId
if (data.icon != null) {
this.icon = { data.icon }
} else if (data.iconId != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt
index 4af9854..40aee65 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt
@@ -41,22 +41,13 @@
if (data.isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
secondaryLabel = subtitleArray[2]
- icon = {
- Icon.Loaded(
- resources.getDrawable(R.drawable.qs_invert_colors_icon_on, theme),
- null
- )
- }
+ iconRes = R.drawable.qs_invert_colors_icon_on
} else {
activationState = QSTileState.ActivationState.INACTIVE
secondaryLabel = subtitleArray[1]
- icon = {
- Icon.Loaded(
- resources.getDrawable(R.drawable.qs_invert_colors_icon_off, theme),
- null
- )
- }
+ iconRes = R.drawable.qs_invert_colors_icon_off
}
+ icon = { Icon.Loaded(resources.getDrawable(iconRes!!, theme), null) }
contentDescription = label
supportedActions =
setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
index fe5445d..d58f5ab 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
@@ -37,14 +37,16 @@
override fun map(config: QSTileConfig, data: LocationTileModel): QSTileState =
QSTileState.build(resources, theme, config.uiConfig) {
+ iconRes =
+ if (data.isEnabled) {
+ R.drawable.qs_location_icon_on
+ } else {
+ R.drawable.qs_location_icon_off
+ }
val icon =
Icon.Loaded(
resources.getDrawable(
- if (data.isEnabled) {
- R.drawable.qs_location_icon_on
- } else {
- R.drawable.qs_location_icon_off
- },
+ iconRes!!,
theme,
),
contentDescription = null
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt
index 5c2dcfc..bcf7cc7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt
@@ -52,21 +52,14 @@
if (data.isActivated) {
activationState = QSTileState.ActivationState.ACTIVE
- val loadedIcon =
- Icon.Loaded(
- resources.getDrawable(R.drawable.qs_nightlight_icon_on, theme),
- contentDescription = null
- )
- icon = { loadedIcon }
+ iconRes = R.drawable.qs_nightlight_icon_on
} else {
activationState = QSTileState.ActivationState.INACTIVE
- val loadedIcon =
- Icon.Loaded(
- resources.getDrawable(R.drawable.qs_nightlight_icon_off, theme),
- contentDescription = null
- )
- icon = { loadedIcon }
+ iconRes = R.drawable.qs_nightlight_icon_off
}
+ val loadedIcon =
+ Icon.Loaded(resources.getDrawable(iconRes!!, theme), contentDescription = null)
+ icon = { loadedIcon }
secondaryLabel = getSecondaryLabel(data, resources)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt
index 9166ed8..4080996 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt
@@ -38,15 +38,8 @@
QSTileState.build(resources, theme, config.uiConfig) {
val subtitleArray = resources.getStringArray(R.array.tile_states_onehanded)
label = resources.getString(R.string.quick_settings_onehanded_label)
- icon = {
- Icon.Loaded(
- resources.getDrawable(
- com.android.internal.R.drawable.ic_qs_one_handed_mode,
- theme
- ),
- null
- )
- }
+ iconRes = com.android.internal.R.drawable.ic_qs_one_handed_mode
+ icon = { Icon.Loaded(resources.getDrawable(iconRes!!, theme), null) }
if (data.isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
secondaryLabel = subtitleArray[2]
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt
index 45a7717..8231742 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt
@@ -38,9 +38,8 @@
QSTileState.build(resources, theme, config.uiConfig) {
label = resources.getString(R.string.qr_code_scanner_title)
contentDescription = label
- icon = {
- Icon.Loaded(resources.getDrawable(R.drawable.ic_qr_code_scanner, theme), null)
- }
+ iconRes = R.drawable.ic_qr_code_scanner
+ icon = { Icon.Loaded(resources.getDrawable(iconRes!!, theme), null) }
sideViewIcon = QSTileState.SideViewIcon.Chevron
supportedActions = setOf(QSTileState.UserAction.CLICK)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt
index fca93df..85ee022 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt
@@ -39,28 +39,23 @@
QSTileState.build(resources, theme, config.uiConfig) {
if (data.isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
- icon = {
- Icon.Loaded(
- drawable = resources.getDrawable(R.drawable.qs_extra_dim_icon_on, theme),
- contentDescription = null
- )
- }
-
+ iconRes = R.drawable.qs_extra_dim_icon_on
secondaryLabel =
resources
.getStringArray(R.array.tile_states_reduce_brightness)[Tile.STATE_ACTIVE]
} else {
activationState = QSTileState.ActivationState.INACTIVE
- icon = {
- Icon.Loaded(
- drawable = resources.getDrawable(R.drawable.qs_extra_dim_icon_off, theme),
- contentDescription = null
- )
- }
+ iconRes = R.drawable.qs_extra_dim_icon_off
secondaryLabel =
resources
.getStringArray(R.array.tile_states_reduce_brightness)[Tile.STATE_INACTIVE]
}
+ icon = {
+ Icon.Loaded(
+ drawable = resources.getDrawable(iconRes!!, theme),
+ contentDescription = null
+ )
+ }
label =
resources.getString(com.android.internal.R.string.reduce_bright_colors_feature_name)
contentDescription = label
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
index 070cdef..8e80fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
@@ -44,12 +44,7 @@
if (data.isRotationLocked) {
activationState = QSTileState.ActivationState.INACTIVE
this.secondaryLabel = EMPTY_SECONDARY_STRING
- this.icon = {
- Icon.Loaded(
- resources.getDrawable(R.drawable.qs_auto_rotate_icon_off, theme),
- contentDescription = null
- )
- }
+ iconRes = R.drawable.qs_auto_rotate_icon_off
} else {
activationState = QSTileState.ActivationState.ACTIVE
this.secondaryLabel =
@@ -58,12 +53,10 @@
} else {
EMPTY_SECONDARY_STRING
}
- this.icon = {
- Icon.Loaded(
- resources.getDrawable(R.drawable.qs_auto_rotate_icon_on, theme),
- contentDescription = null
- )
- }
+ this.iconRes = R.drawable.qs_auto_rotate_icon_on
+ }
+ this.icon = {
+ Icon.Loaded(resources.getDrawable(iconRes!!, theme), contentDescription = null)
}
if (isDeviceFoldable()) {
this.secondaryLabel = getSecondaryLabelWithPosture(this.activationState)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt
index df25600..888bba87 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt
@@ -36,7 +36,6 @@
override fun map(config: QSTileConfig, data: DataSaverTileModel): QSTileState =
QSTileState.build(resources, theme, config.uiConfig) {
with(data) {
- val iconRes: Int
if (isEnabled) {
activationState = QSTileState.ActivationState.ACTIVE
iconRes = R.drawable.qs_data_saver_icon_on
@@ -47,7 +46,7 @@
secondaryLabel = resources.getStringArray(R.array.tile_states_saver)[1]
}
val loadedIcon =
- Icon.Loaded(resources.getDrawable(iconRes, theme), contentDescription = null)
+ Icon.Loaded(resources.getDrawable(iconRes!!, theme), contentDescription = null)
icon = { loadedIcon }
contentDescription = label
supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
index b58774b..7446708 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
@@ -42,9 +42,10 @@
when (data) {
is ScreenRecordModel.Recording -> {
activationState = QSTileState.ActivationState.ACTIVE
+ iconRes = R.drawable.qs_screen_record_icon_on
val loadedIcon =
Icon.Loaded(
- resources.getDrawable(R.drawable.qs_screen_record_icon_on, theme),
+ resources.getDrawable(iconRes!!, theme),
contentDescription = null
)
icon = { loadedIcon }
@@ -53,9 +54,10 @@
}
is ScreenRecordModel.Starting -> {
activationState = QSTileState.ActivationState.ACTIVE
+ iconRes = R.drawable.qs_screen_record_icon_on
val loadedIcon =
Icon.Loaded(
- resources.getDrawable(R.drawable.qs_screen_record_icon_on, theme),
+ resources.getDrawable(iconRes!!, theme),
contentDescription = null
)
icon = { loadedIcon }
@@ -65,9 +67,10 @@
}
is ScreenRecordModel.DoingNothing -> {
activationState = QSTileState.ActivationState.INACTIVE
+ iconRes = R.drawable.qs_screen_record_icon_off
val loadedIcon =
Icon.Loaded(
- resources.getDrawable(R.drawable.qs_screen_record_icon_off, theme),
+ resources.getDrawable(iconRes!!, theme),
contentDescription = null
)
icon = { loadedIcon }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt
index 52622d2..597cf27 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt
@@ -50,15 +50,8 @@
contentDescription = label
supportedActions =
setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
- icon = {
- Icon.Loaded(
- resources.getDrawable(
- sensorPrivacyTileResources.getIconRes(data.isBlocked),
- theme
- ),
- null
- )
- }
+ iconRes = sensorPrivacyTileResources.getIconRes(data.isBlocked)
+ icon = { Icon.Loaded(resources.getDrawable(iconRes!!, theme), null) }
sideViewIcon = QSTileState.SideViewIcon.None
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt
index ffef2b6..f29c745d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt
@@ -117,12 +117,12 @@
}
}
- val iconRes =
+ iconRes =
if (activationState == QSTileState.ActivationState.ACTIVE)
R.drawable.qs_light_dark_theme_icon_on
else R.drawable.qs_light_dark_theme_icon_off
val loadedIcon =
- Icon.Loaded(resources.getDrawable(iconRes, theme), contentDescription = null)
+ Icon.Loaded(resources.getDrawable(iconRes!!, theme), contentDescription = null)
icon = { loadedIcon }
supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt
index 55445bb..eee95b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt
@@ -41,15 +41,9 @@
QSTileState.build(resources, theme, config.uiConfig) {
label = getTileLabel()!!
contentDescription = label
-
+ iconRes = com.android.internal.R.drawable.stat_sys_managed_profile_status
icon = {
- Icon.Loaded(
- resources.getDrawable(
- com.android.internal.R.drawable.stat_sys_managed_profile_status,
- theme
- ),
- contentDescription = null
- )
+ Icon.Loaded(resources.getDrawable(iconRes!!, theme), contentDescription = null)
}
when (data) {
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 b927e41..ae6c014 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
@@ -29,10 +29,14 @@
* [QSTileState.build] for better state creation experience and preset default values for certain
* fields.
*
+ * @param iconRes For when we want to have Loaded icon, but still keep a reference to the resource
+ * id. A use case would be for tests that have to compare animated drawables.
+ *
* // TODO(b/http://b/299909989): Clean up legacy mappings after the transition
*/
data class QSTileState(
val icon: () -> Icon?,
+ val iconRes: Int?,
val label: CharSequence,
val activationState: ActivationState,
val secondaryLabel: CharSequence?,
@@ -111,6 +115,7 @@
var icon: () -> Icon?,
var label: CharSequence,
) {
+ var iconRes: Int? = null
var activationState: ActivationState = ActivationState.INACTIVE
var secondaryLabel: CharSequence? = null
var supportedActions: Set<UserAction> = setOf(UserAction.CLICK)
@@ -123,6 +128,7 @@
fun build(): QSTileState =
QSTileState(
icon,
+ iconRes,
label,
activationState,
secondaryLabel,
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 5346b23..7be13e0 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
@@ -28,6 +28,7 @@
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon
+import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes
import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -241,7 +242,9 @@
iconSupplier = Supplier {
when (val stateIcon = viewModelState.icon()) {
- is Icon.Loaded -> DrawableIcon(stateIcon.drawable)
+ is Icon.Loaded ->
+ if (viewModelState.iconRes == null) DrawableIcon(stateIcon.drawable)
+ else DrawableIconWithRes(stateIcon.drawable, viewModelState.iconRes)
is Icon.Resource -> ResourceIcon.get(stateIcon.res)
null -> null
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
index fb872d5..c7326b08 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
@@ -46,7 +46,6 @@
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.BufferOverflow
-import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -89,8 +88,10 @@
/**
* A view with the QS content ([QSContainerImpl]), managed by an instance of [QSImpl] tracked by
* the interactor.
+ *
+ * A null value means that there is no inflated view yet. See [inflate].
*/
- val qsView: Flow<View>
+ val qsView: StateFlow<View?>
/** Sets the [MirrorController] in [QSImpl]. Set to `null` to remove. */
fun setBrightnessMirrorController(mirrorController: MirrorController?)
@@ -101,9 +102,22 @@
*/
suspend fun inflate(context: Context)
- /** Set the current state for QS. [state]. */
+ /**
+ * Set the current state for QS. [state].
+ *
+ * This will not trigger expansion (animation between QQS or QS) or squishiness to be applied.
+ * For that, use [applyLatestExpansionAndSquishiness] outside of the composition phase.
+ */
fun setState(state: State)
+ /**
+ * Explicitly applies the expansion and squishiness value from the latest state set. Call this
+ * only outside of the composition phase as this will call [QSImpl.setQsExpansion] that is
+ * normally called during animations. In particular, this will read the value of
+ * [State.squishiness], that is not safe to read in the composition phase.
+ */
+ fun applyLatestExpansionAndSquishiness()
+
/** Propagates the bottom nav bar size to [QSImpl] to be used as necessary. */
suspend fun applyBottomNavBarPadding(padding: Int)
@@ -141,14 +155,24 @@
override val squishiness = { 1f }
}
- /** State for appearing QQS from Lockscreen or Gone */
- data class UnsquishingQQS(override val squishiness: () -> Float) : State {
+ /**
+ * State for appearing QQS from Lockscreen or Gone.
+ *
+ * This should not be a data class, as it has a method parameter and even if it's the same
+ * lambda the output value may have changed.
+ */
+ class UnsquishingQQS(override val squishiness: () -> Float) : State {
override val isVisible = true
override val expansion = 0f
}
- /** State for appearing QS from Lockscreen or Gone, used in Split shade */
- data class UnsquishingQS(override val squishiness: () -> Float) : State {
+ /**
+ * State for appearing QS from Lockscreen or Gone, used in Split shade.
+ *
+ * This should not be a data class, as it has a method parameter and even if it's the same
+ * lambda the output value may have changed.
+ */
+ class UnsquishingQS(override val squishiness: () -> Float) : State {
override val isVisible = true
override val expansion = 1f
}
@@ -236,7 +260,10 @@
private val _qsImpl: MutableStateFlow<QSImpl?> = MutableStateFlow(null)
val qsImpl = _qsImpl.asStateFlow()
- override val qsView: Flow<View> = _qsImpl.map { it?.view }.filterNotNull()
+ override val qsView: StateFlow<View?> =
+ _qsImpl
+ .map { it?.view }
+ .stateIn(applicationScope, SharingStarted.WhileSubscribed(), _qsImpl.value?.view)
override val qqsHeight: Int
get() = qsImpl.value?.qqsHeight ?: 0
@@ -370,7 +397,12 @@
setQsVisible(state.isVisible)
setExpanded(state.isVisible && state.expansion > 0f)
setListening(state.isVisible)
- setQsExpansion(state.expansion, 1f, 0f, state.squishiness())
+ }
+
+ override fun applyLatestExpansionAndSquishiness() {
+ val qsImpl = _qsImpl.value
+ val state = state.value
+ qsImpl?.setQsExpansion(state.expansion, 1f, 0f, state.squishiness())
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index 5469a4e..e024710 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -119,6 +119,7 @@
IMediaProjection projection = IMediaProjection.Stub.asInterface(proj.asBinder());
if (mCaptureRegion != null) {
projection.setLaunchCookie(mCaptureRegion.getLaunchCookie());
+ projection.setTaskId(mCaptureRegion.getTaskId());
}
mMediaProjection = new MediaProjection(mContext, projection);
mMediaProjection.registerCallback(this, mHandler);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
index 4ab0918..9e62280 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
@@ -90,12 +90,18 @@
)
}
systemUiProxy.dismissKeyguard()
- transitionCoordinator?.startExit()
+ var transitionOptions: ActivityOptions? = null
+ if (transitionCoordinator?.decor?.isAttachedToWindow == true) {
+ transitionCoordinator.startExit()
+ transitionOptions = options
+ }
if (user == myUserHandle()) {
- withContext(mainDispatcher) { context.startActivity(intent, options?.toBundle()) }
+ withContext(mainDispatcher) {
+ context.startActivity(intent, transitionOptions?.toBundle())
+ }
} else {
- launchCrossProfileIntent(user, intent, options?.toBundle())
+ launchCrossProfileIntent(user, intent, transitionOptions?.toBundle())
}
if (overrideTransition) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsController.kt
new file mode 100644
index 0000000..2ffb783
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsController.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.screenshot
+
+import android.app.assist.AssistContent
+import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance
+import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.util.UUID
+
+/**
+ * Responsible for obtaining the actions for each screenshot and sending them to the view model.
+ * Ensures that only actions from screenshots that are currently being shown are added to the view
+ * model.
+ */
+class ScreenshotActionsController
+@AssistedInject
+constructor(
+ private val viewModel: ScreenshotViewModel,
+ private val actionsProviderFactory: ScreenshotActionsProvider.Factory,
+ @Assisted val actionExecutor: ActionExecutor
+) {
+ private val actionProviders: MutableMap<UUID, ScreenshotActionsProvider> = mutableMapOf()
+ private var currentScreenshotId: UUID? = null
+
+ fun setCurrentScreenshot(screenshot: ScreenshotData): UUID {
+ val screenshotId = UUID.randomUUID()
+ currentScreenshotId = screenshotId
+ actionProviders[screenshotId] =
+ actionsProviderFactory.create(
+ screenshotId,
+ screenshot,
+ actionExecutor,
+ ActionsCallback(screenshotId),
+ )
+ return screenshotId
+ }
+
+ fun endScreenshotSession() {
+ currentScreenshotId = null
+ }
+
+ fun onAssistContent(screenshotId: UUID, assistContent: AssistContent?) {
+ actionProviders[screenshotId]?.onAssistContent(assistContent)
+ }
+
+ fun onScrollChipReady(screenshotId: UUID, onClick: Runnable) {
+ if (screenshotId == currentScreenshotId) {
+ actionProviders[screenshotId]?.onScrollChipReady(onClick)
+ }
+ }
+
+ fun onScrollChipInvalidated() {
+ for (provider in actionProviders.values) {
+ provider.onScrollChipInvalidated()
+ }
+ }
+
+ fun setCompletedScreenshot(screenshotId: UUID, result: ScreenshotSavedResult) {
+ if (screenshotId == currentScreenshotId) {
+ actionProviders[screenshotId]?.setCompletedScreenshot(result)
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun getController(actionExecutor: ActionExecutor): ScreenshotActionsController
+ }
+
+ inner class ActionsCallback(private val screenshotId: UUID) {
+ fun providePreviewAction(onClick: () -> Unit) {
+ if (screenshotId == currentScreenshotId) {
+ viewModel.setPreviewAction(onClick)
+ }
+ }
+
+ fun provideActionButton(
+ appearance: ActionButtonAppearance,
+ showDuringEntrance: Boolean,
+ onClick: () -> Unit
+ ): Int {
+ if (screenshotId == currentScreenshotId) {
+ return viewModel.addAction(appearance, showDuringEntrance, onClick)
+ }
+ return 0
+ }
+
+ fun updateActionButtonAppearance(buttonId: Int, appearance: ActionButtonAppearance) {
+ if (screenshotId == currentScreenshotId) {
+ viewModel.updateActionAppearance(buttonId, appearance)
+ }
+ }
+
+ fun updateActionButtonVisibility(buttonId: Int, visible: Boolean) {
+ if (screenshotId == currentScreenshotId) {
+ viewModel.setActionVisibility(buttonId, visible)
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
index a1dd415..b8029c8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
@@ -29,10 +29,10 @@
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SHARE_TAPPED
import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance
-import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
+import java.util.UUID
/**
* Provides actions for screenshots. This class can be overridden by a vendor-specific SysUI
@@ -51,9 +51,10 @@
interface Factory {
fun create(
+ requestId: UUID,
request: ScreenshotData,
- requestId: String,
actionExecutor: ActionExecutor,
+ actionsCallback: ScreenshotActionsController.ActionsCallback,
): ScreenshotActionsProvider
}
}
@@ -62,11 +63,11 @@
@AssistedInject
constructor(
private val context: Context,
- private val viewModel: ScreenshotViewModel,
private val uiEventLogger: UiEventLogger,
+ @Assisted val requestId: UUID,
@Assisted val request: ScreenshotData,
- @Assisted val requestId: String,
@Assisted val actionExecutor: ActionExecutor,
+ @Assisted val actionsCallback: ScreenshotActionsController.ActionsCallback,
) : ScreenshotActionsProvider {
private var addedScrollChip = false
private var onScrollClick: Runnable? = null
@@ -74,7 +75,7 @@
private var result: ScreenshotSavedResult? = null
init {
- viewModel.setPreviewAction {
+ actionsCallback.providePreviewAction {
debugLog(LogConfig.DEBUG_ACTIONS) { "Preview tapped" }
uiEventLogger.log(SCREENSHOT_PREVIEW_TAPPED, 0, request.packageNameString)
onDeferrableActionTapped { result ->
@@ -85,26 +86,8 @@
)
}
}
- viewModel.addAction(
- ActionButtonAppearance(
- AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
- context.resources.getString(R.string.screenshot_edit_label),
- context.resources.getString(R.string.screenshot_edit_description),
- ),
- showDuringEntrance = true,
- ) {
- debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" }
- uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString)
- onDeferrableActionTapped { result ->
- actionExecutor.startSharedTransition(
- createEdit(result.uri, context),
- result.user,
- true
- )
- }
- }
- viewModel.addAction(
+ actionsCallback.provideActionButton(
ActionButtonAppearance(
AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share),
context.resources.getString(R.string.screenshot_share_label),
@@ -122,12 +105,31 @@
)
}
}
+
+ actionsCallback.provideActionButton(
+ ActionButtonAppearance(
+ AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
+ context.resources.getString(R.string.screenshot_edit_label),
+ context.resources.getString(R.string.screenshot_edit_description),
+ ),
+ showDuringEntrance = true,
+ ) {
+ debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" }
+ uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString)
+ onDeferrableActionTapped { result ->
+ actionExecutor.startSharedTransition(
+ createEdit(result.uri, context),
+ result.user,
+ true
+ )
+ }
+ }
}
override fun onScrollChipReady(onClick: Runnable) {
onScrollClick = onClick
if (!addedScrollChip) {
- viewModel.addAction(
+ actionsCallback.provideActionButton(
ActionButtonAppearance(
AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_scroll),
context.resources.getString(R.string.screenshot_scroll_label),
@@ -161,9 +163,10 @@
@AssistedFactory
interface Factory : ScreenshotActionsProvider.Factory {
override fun create(
+ requestId: UUID,
request: ScreenshotData,
- requestId: String,
actionExecutor: ActionExecutor,
+ actionsCallback: ScreenshotActionsController.ActionsCallback,
): DefaultScreenshotActionsProvider
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 01adab3..e8dfac8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -192,7 +192,6 @@
private final WindowContext mContext;
private final FeatureFlags mFlags;
private final ScreenshotViewProxy mViewProxy;
- private final ScreenshotActionsProvider.Factory mActionsProviderFactory;
private final ScreenshotNotificationsController mNotificationsController;
private final ScreenshotSmartActions mScreenshotSmartActions;
private final UiEventLogger mUiEventLogger;
@@ -202,7 +201,7 @@
private final ExecutorService mBgExecutor;
private final BroadcastSender mBroadcastSender;
private final BroadcastDispatcher mBroadcastDispatcher;
- private final ActionExecutor mActionExecutor;
+ private final ScreenshotActionsController mActionsController;
private final WindowManager mWindowManager;
private final WindowManager.LayoutParams mWindowLayoutParams;
@@ -217,6 +216,8 @@
private final ActionIntentExecutor mActionIntentExecutor;
private final UserManager mUserManager;
private final AssistContentRequester mAssistContentRequester;
+ private final ActionExecutor mActionExecutor;
+
private final MessageContainerController mMessageContainerController;
private final AnnouncementResolver mAnnouncementResolver;
@@ -227,7 +228,6 @@
private boolean mDetachRequested;
private Animator mScreenshotAnimation;
private RequestCallback mCurrentRequestCallback;
- private ScreenshotActionsProvider mActionsProvider;
private String mPackageName = "";
private final BroadcastReceiver mCopyBroadcastReceiver;
@@ -254,7 +254,6 @@
WindowManager windowManager,
FeatureFlags flags,
ScreenshotViewProxy.Factory viewProxyFactory,
- ScreenshotActionsProvider.Factory actionsProviderFactory,
ScreenshotSmartActions screenshotSmartActions,
ScreenshotNotificationsController.Factory screenshotNotificationsControllerFactory,
UiEventLogger uiEventLogger,
@@ -266,6 +265,7 @@
BroadcastSender broadcastSender,
BroadcastDispatcher broadcastDispatcher,
ScreenshotNotificationSmartActionsProvider screenshotNotificationSmartActionsProvider,
+ ScreenshotActionsController.Factory screenshotActionsControllerFactory,
ActionIntentExecutor actionIntentExecutor,
ActionExecutor.Factory actionExecutorFactory,
UserManager userManager,
@@ -277,7 +277,6 @@
@Assisted boolean showUIOnExternalDisplay
) {
mScreenshotSmartActions = screenshotSmartActions;
- mActionsProviderFactory = actionsProviderFactory;
mNotificationsController = screenshotNotificationsControllerFactory.create(
display.getDisplayId());
mUiEventLogger = uiEventLogger;
@@ -328,6 +327,8 @@
finishDismiss();
return Unit.INSTANCE;
});
+ mActionsController = screenshotActionsControllerFactory.getController(mActionExecutor);
+
// Sound is only reproduced from the controller of the default display.
if (mDisplay.getDisplayId() == Display.DEFAULT_DISPLAY) {
@@ -404,20 +405,21 @@
return;
}
+ final UUID requestId;
if (screenshotShelfUi2()) {
- final UUID requestId = UUID.randomUUID();
- final String screenshotId = String.format("Screenshot_%s", requestId);
- mActionsProvider = mActionsProviderFactory.create(
- screenshot, screenshotId, mActionExecutor);
+ requestId = mActionsController.setCurrentScreenshot(screenshot);
saveScreenshotInBackground(screenshot, requestId, finisher);
if (screenshot.getTaskId() >= 0) {
- mAssistContentRequester.requestAssistContent(screenshot.getTaskId(),
- assistContent -> mActionsProvider.onAssistContent(assistContent));
+ mAssistContentRequester.requestAssistContent(
+ screenshot.getTaskId(),
+ assistContent ->
+ mActionsController.onAssistContent(requestId, assistContent));
} else {
- mActionsProvider.onAssistContent(null);
+ mActionsController.onAssistContent(requestId, null);
}
} else {
+ requestId = UUID.randomUUID(); // passed through but unused for legacy UI
saveScreenshotInWorkerThread(screenshot.getUserHandle(), finisher,
this::showUiOnActionsReady, this::showUiOnQuickShareActionReady);
}
@@ -426,7 +428,7 @@
setWindowFocusable(true);
mViewProxy.requestFocus();
- enqueueScrollCaptureRequest(screenshot.getUserHandle());
+ enqueueScrollCaptureRequest(requestId, screenshot.getUserHandle());
attachWindow();
@@ -587,11 +589,11 @@
mWindow.setContentView(mViewProxy.getView());
}
- private void enqueueScrollCaptureRequest(UserHandle owner) {
+ private void enqueueScrollCaptureRequest(UUID requestId, UserHandle owner) {
// Wait until this window is attached to request because it is
// the reference used to locate the target window (below).
withWindowAttached(() -> {
- requestScrollCapture(owner);
+ requestScrollCapture(requestId, owner);
mWindow.peekDecorView().getViewRootImpl().setActivityConfigCallback(
new ViewRootImpl.ActivityConfigCallback() {
@Override
@@ -601,14 +603,14 @@
// Hide the scroll chip until we know it's available in this
// orientation
if (screenshotShelfUi2()) {
- mActionsProvider.onScrollChipInvalidated();
+ mActionsController.onScrollChipInvalidated();
} else {
mViewProxy.hideScrollChip();
}
// Delay scroll capture eval a bit to allow the underlying activity
// to set up in the new orientation.
mScreenshotHandler.postDelayed(
- () -> requestScrollCapture(owner), 150);
+ () -> requestScrollCapture(requestId, owner), 150);
mViewProxy.updateInsets(
mWindowManager.getCurrentWindowMetrics().getWindowInsets());
// Screenshot animation calculations won't be valid anymore,
@@ -630,7 +632,7 @@
});
}
- private void requestScrollCapture(UserHandle owner) {
+ private void requestScrollCapture(UUID requestId, UserHandle owner) {
mScrollCaptureExecutor.requestScrollCapture(
mDisplay.getDisplayId(),
mWindow.getDecorView().getWindowToken(),
@@ -638,10 +640,8 @@
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_IMPRESSION,
0, response.getPackageName());
if (screenshotShelfUi2()) {
- if (mActionsProvider != null) {
- mActionsProvider.onScrollChipReady(
- () -> onScrollButtonClicked(owner, response));
- }
+ mActionsController.onScrollChipReady(requestId,
+ () -> onScrollButtonClicked(owner, response));
} else {
mViewProxy.showScrollChip(response.getPackageName(),
() -> onScrollButtonClicked(owner, response));
@@ -832,6 +832,7 @@
/** Reset screenshot view and then call onCompleteRunnable */
private void finishDismiss() {
Log.d(TAG, "finishDismiss");
+ mActionsController.endScreenshotSession();
mScrollCaptureExecutor.close();
if (mCurrentRequestCallback != null) {
mCurrentRequestCallback.onFinish();
@@ -852,9 +853,8 @@
ImageExporter.Result result = future.get();
Log.d(TAG, "Saved screenshot: " + result);
logScreenshotResultStatus(result.uri, screenshot.getUserHandle());
- mScreenshotHandler.resetTimeout();
if (result.uri != null) {
- mActionsProvider.setCompletedScreenshot(new ScreenshotSavedResult(
+ mActionsController.setCompletedScreenshot(requestId, new ScreenshotSavedResult(
result.uri, screenshot.getUserOrDefault(), result.timestamp));
}
if (DEBUG_CALLBACK) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/FlingInfo.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FlingInfo.kt
index d7f96e6..ea2f9ab 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/FlingInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FlingInfo.kt
@@ -16,11 +16,16 @@
package com.android.systemui.shade.data.repository
+import java.util.UUID
+
/**
* Information about a fling on the shade: whether we're flinging expanded or collapsed, and the
* velocity of the touch gesture that started the fling (if applicable).
*/
-data class FlingInfo(
+data class FlingInfo @JvmOverloads constructor(
val expand: Boolean,
val velocity: Float = 0f,
+
+ /** Required to emit duplicate FlingInfo from StateFlow. */
+ val id: UUID = UUID.randomUUID()
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 5bf2f41..03c6670 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -15,7 +15,7 @@
*/
package com.android.systemui.statusbar;
-import static com.android.systemui.Flags.mediaControlsUserInitiatedDismiss;
+import static com.android.systemui.Flags.mediaControlsUserInitiatedDeleteintent;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -178,7 +178,7 @@
@Override
public void onMediaDataRemoved(@NonNull String key, boolean userInitiated) {
- if (mediaControlsUserInitiatedDismiss() && !userInitiated) {
+ if (mediaControlsUserInitiatedDeleteintent() && !userInitiated) {
// Dismissing the notification will send the app's deleteIntent, so ignore if
// this was an automatic removal
Log.d(TAG, "Not dismissing " + key + " because it was removed by the system");
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 6546db9..2ab7aa9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -42,7 +42,10 @@
private val activityStarterInternal: ActivityStarterInternal = legacyActivityStarter.get()
override fun startPendingIntentDismissingKeyguard(intent: PendingIntent) {
- activityStarterInternal.startPendingIntentDismissingKeyguard(intent = intent)
+ activityStarterInternal.startPendingIntentDismissingKeyguard(
+ intent = intent,
+ dismissShade = true
+ )
}
override fun startPendingIntentDismissingKeyguard(
@@ -52,6 +55,7 @@
activityStarterInternal.startPendingIntentDismissingKeyguard(
intent = intent,
intentSentUiThreadCallback = intentSentUiThreadCallback,
+ dismissShade = true,
)
}
@@ -64,6 +68,7 @@
intent = intent,
intentSentUiThreadCallback = intentSentUiThreadCallback,
associatedView = associatedView,
+ dismissShade = true,
)
}
@@ -76,6 +81,7 @@
intent = intent,
intentSentUiThreadCallback = intentSentUiThreadCallback,
animationController = animationController,
+ dismissShade = true,
)
}
@@ -89,11 +95,13 @@
intentSentUiThreadCallback = intentSentUiThreadCallback,
animationController = animationController,
showOverLockscreen = true,
+ dismissShade = true,
)
}
override fun startPendingIntentMaybeDismissingKeyguard(
intent: PendingIntent,
+ dismissShade: Boolean,
intentSentUiThreadCallback: Runnable?,
animationController: ActivityTransitionAnimator.Controller?,
fillInIntent: Intent?,
@@ -104,6 +112,7 @@
intentSentUiThreadCallback = intentSentUiThreadCallback,
animationController = animationController,
showOverLockscreen = true,
+ dismissShade = dismissShade,
fillInIntent = fillInIntent,
extraOptions = extraOptions,
)
@@ -179,6 +188,7 @@
showOverLockscreenWhenLocked = showOverLockscreenWhenLocked,
)
}
+
override fun startActivity(
intent: Intent,
dismissShade: Boolean,
@@ -199,6 +209,7 @@
postOnUiThread {
activityStarterInternal.startPendingIntentDismissingKeyguard(
intent = intent,
+ dismissShade = true,
)
}
}
@@ -211,6 +222,7 @@
activityStarterInternal.startPendingIntentDismissingKeyguard(
intent = intent,
animationController = animationController,
+ dismissShade = true,
)
}
}
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 e844398..c9becb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
@@ -34,6 +34,7 @@
*/
fun startPendingIntentDismissingKeyguard(
intent: PendingIntent,
+ dismissShade: Boolean,
intentSentUiThreadCallback: Runnable? = null,
associatedView: View? = null,
animationController: ActivityTransitionAnimator.Controller? = null,
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 c101755..e580f64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
@@ -35,6 +35,7 @@
class ActivityStarterInternalImpl @Inject constructor() : ActivityStarterInternal {
override fun startPendingIntentDismissingKeyguard(
intent: PendingIntent,
+ dismissShade: Boolean,
intentSentUiThreadCallback: Runnable?,
associatedView: View?,
animationController: ActivityTransitionAnimator.Controller?,
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 8fb552f..7b7a35b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -199,6 +199,11 @@
boolean isLaunchingActivityOverLockscreen();
+ /**
+ * Whether an activity launch over lockscreen is causing the shade to be dismissed.
+ */
+ boolean isDismissingShadeForActivityLaunch();
+
void onKeyguardViewManagerStatesUpdated();
/** */
@@ -333,7 +338,8 @@
/**
* Sets launching activity over LS state in central surfaces.
*/
- void setIsLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen);
+ void setIsLaunchingActivityOverLockscreen(
+ boolean isLaunchingActivityOverLockscreen, boolean dismissShade);
/**
* Gets an animation controller from a notification row.
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 8af7ee8..5ab56ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
@@ -39,6 +39,7 @@
override fun updateIsKeyguard(forceStateChange: Boolean) = false
override fun getKeyguardMessageArea(): AuthKeyguardMessageArea? = null
override fun isLaunchingActivityOverLockscreen() = false
+ override fun isDismissingShadeForActivityLaunch() = false
override fun onKeyguardViewManagerStatesUpdated() {}
override fun getCommandQueuePanelsEnabled() = false
override fun showWirelessChargingAnimation(batteryLevel: Int) {}
@@ -96,7 +97,10 @@
override fun setLaunchEmergencyActionOnFinishedWaking(launch: Boolean) {}
override fun getQSPanelController(): QSPanelController? = null
override fun getDisplayDensity() = 0f
- override fun setIsLaunchingActivityOverLockscreen(isLaunchingActivityOverLockscreen: Boolean) {}
+ override fun setIsLaunchingActivityOverLockscreen(
+ isLaunchingActivityOverLockscreen: Boolean,
+ dismissShade: Boolean,
+ ) {}
override fun getAnimatorControllerFromNotification(
associatedView: ExpandableNotificationRow?,
): ActivityTransitionAnimator.Controller? = null
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 d3d2b1e..e0da2fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -544,6 +544,7 @@
// Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
private int mLastLoggedStateFingerprint;
private boolean mIsLaunchingActivityOverLockscreen;
+ private boolean mDismissingShadeForActivityLaunch;
private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
protected final BatteryController mBatteryController;
@@ -1575,6 +1576,11 @@
return mIsLaunchingActivityOverLockscreen;
}
+ @Override
+ public boolean isDismissingShadeForActivityLaunch() {
+ return mDismissingShadeForActivityLaunch;
+ }
+
/**
* To be called when there's a state change in StatusBarKeyguardViewManager.
*/
@@ -3306,8 +3312,10 @@
}
@Override
- public void setIsLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {
+ public void setIsLaunchingActivityOverLockscreen(
+ boolean isLaunchingActivityOverLockscreen, boolean dismissShade) {
mIsLaunchingActivityOverLockscreen = isLaunchingActivityOverLockscreen;
+ mDismissingShadeForActivityLaunch = dismissShade;
mKeyguardViewMediator.launchingActivityOverLockscreen(mIsLaunchingActivityOverLockscreen);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 11feb97..f99a81e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -159,7 +159,7 @@
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (shouldBeVisible()) {
- updateTopEntry();
+ updateTopEntry("onLayoutChange");
// trigger scroller to notify the latest panel translation
mStackScrollerController.requestLayout();
@@ -220,7 +220,7 @@
@Override
public void onHeadsUpPinned(NotificationEntry entry) {
- updateTopEntry();
+ updateTopEntry("onHeadsUpPinned");
updateHeader(entry);
updateHeadsUpAndPulsingRoundness(entry);
}
@@ -231,7 +231,7 @@
mPhoneStatusBarTransitions.onHeadsUpStateChanged(isHeadsUp);
}
- private void updateTopEntry() {
+ private void updateTopEntry(String reason) {
NotificationEntry newEntry = null;
if (shouldBeVisible()) {
newEntry = mHeadsUpManager.getTopEntry();
@@ -370,7 +370,7 @@
@Override
public void onHeadsUpUnPinned(NotificationEntry entry) {
- updateTopEntry();
+ updateTopEntry("onHeadsUpUnPinned");
updateHeader(entry);
updateHeadsUpAndPulsingRoundness(entry);
}
@@ -388,7 +388,7 @@
updateHeadsUpHeaders();
}
if (isExpanded() != oldIsExpanded) {
- updateTopEntry();
+ updateTopEntry("setAppearFraction");
}
}
@@ -462,11 +462,11 @@
}
public void onStateChanged() {
- updateTopEntry();
+ updateTopEntry("onStateChanged");
}
@Override
public void onFullyHiddenChanged(boolean isFullyHidden) {
- updateTopEntry();
+ updateTopEntry("onFullyHiddenChanged");
}
}
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 68457ea..ffc859e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -249,7 +249,7 @@
for (NotificationEntry entry : mEntriesToRemoveAfterExpand) {
if (isHeadsUpEntry(entry.getKey())) {
// Maybe the heads-up was removed already
- removeEntry(entry.getKey());
+ removeEntry(entry.getKey(), "onExpandingFinished");
}
}
}
@@ -381,7 +381,7 @@
for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) {
if (isHeadsUpEntry(entry.getKey())) {
// Maybe the heads-up was removed already
- removeEntry(entry.getKey());
+ removeEntry(entry.getKey(), "mOnReorderingAllowedListener");
}
}
mEntriesToRemoveWhenReorderingAllowed.clear();
@@ -572,7 +572,7 @@
} else if (mTrackingHeadsUp) {
mEntriesToRemoveAfterExpand.add(entry);
} else {
- removeEntry(entry.getKey());
+ removeEntry(entry.getKey(), "createRemoveRunnable");
}
};
}
@@ -661,7 +661,7 @@
}
}
for (String key : keysToRemove) {
- removeEntry(key);
+ removeEntry(key, "mStatusBarStateListener");
}
}
}
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 bcc7db1..b448d85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -33,10 +33,13 @@
import android.view.WindowManager
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.Flags.communalHub
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.animation.DelegateTransitionAnimatorController
import com.android.systemui.assist.AssistManager
import com.android.systemui.camera.CameraIntents
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.DisplayId
import com.android.systemui.dagger.qualifiers.Main
@@ -89,6 +92,7 @@
private val userTracker: UserTracker,
private val activityIntentHelper: ActivityIntentHelper,
@Main private val mainExecutor: DelayableExecutor,
+ private val communalSceneInteractor: CommunalSceneInteractor,
) : ActivityStarterInternal {
private val centralSurfaces: CentralSurfaces?
get() = centralSurfacesOptLazy.get().getOrNull()
@@ -219,6 +223,7 @@
override fun startPendingIntentDismissingKeyguard(
intent: PendingIntent,
+ dismissShade: Boolean,
intentSentUiThreadCallback: Runnable?,
associatedView: View?,
animationController: ActivityTransitionAnimator.Controller?,
@@ -257,12 +262,12 @@
val statusBarController =
wrapAnimationControllerForShadeOrStatusBar(
animationController = animationController,
- dismissShade = true,
+ dismissShade = dismissShade,
isLaunchForActivity = intent.isActivity,
)
val controller =
if (actuallyShowOverLockscreen) {
- wrapAnimationControllerForLockscreen(statusBarController)
+ wrapAnimationControllerForLockscreen(dismissShade, statusBarController)
} else {
statusBarController
}
@@ -270,7 +275,7 @@
// If we animate, don't collapse the shade and defer the keyguard dismiss (in case we
// run the animation on the keyguard). The animation will take care of (instantly)
// collapsing the shade and hiding the keyguard once it is done.
- val collapse = !animate
+ val collapse = dismissShade && !animate
val runnable = Runnable {
try {
activityTransitionAnimator.startPendingIntentWithAnimation(
@@ -377,7 +382,7 @@
dismissShade = dismissShade,
isLaunchForActivity = true,
)
- controller = wrapAnimationControllerForLockscreen(delegate)
+ controller = wrapAnimationControllerForLockscreen(dismissShade, delegate)
} else if (dismissShade) {
// The animation will take care of dismissing the shade at the end of the animation.
// If we don't animate, collapse it directly.
@@ -462,6 +467,9 @@
if (dismissShade) {
shadeControllerLazy.get().collapseShadeForActivityStart()
}
+ if (communalHub()) {
+ communalSceneInteractor.snapToScene(CommunalScenes.Blank)
+ }
return deferred
}
@@ -532,6 +540,7 @@
* lockscreen, the correct flags are set for it to be occluded.
*/
private fun wrapAnimationControllerForLockscreen(
+ dismissShade: Boolean,
animationController: ActivityTransitionAnimator.Controller?
): ActivityTransitionAnimator.Controller? {
return animationController?.let {
@@ -539,7 +548,7 @@
override fun onIntentStarted(willAnimate: Boolean) {
delegate.onIntentStarted(willAnimate)
if (willAnimate) {
- centralSurfaces?.setIsLaunchingActivityOverLockscreen(true)
+ centralSurfaces?.setIsLaunchingActivityOverLockscreen(true, dismissShade)
}
}
@@ -570,7 +579,10 @@
// mIsLaunchingActivityOverLockscreen being true means that we will
// collapse the shade (or at least run the post collapse runnables)
// later on.
- centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
+ centralSurfaces?.setIsLaunchingActivityOverLockscreen(false, false)
+ if (communalHub()) {
+ communalSceneInteractor.snapToScene(CommunalScenes.Blank)
+ }
delegate.onTransitionAnimationEnd(isExpandingFullyAbove)
}
@@ -586,7 +598,7 @@
// mIsLaunchingActivityOverLockscreen being true means that we will
// collapse the shade (or at least run the // post collapse
// runnables) later on.
- centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
+ centralSurfaces?.setIsLaunchingActivityOverLockscreen(false, false)
delegate.onTransitionAnimationCancelled(newKeyguardOccludedState)
}
}
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 5bbc3bd..ebb62ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -1071,12 +1071,17 @@
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__OCCLUDED);
if (mCentralSurfaces.isLaunchingActivityOverLockscreen()) {
- // When isLaunchingActivityOverLockscreen() is true, we know for sure that the post
- // collapse runnables will be run.
- mShadeController.get().addPostCollapseAction(() -> {
+ final Runnable postCollapseAction = () -> {
mNotificationShadeWindowController.setKeyguardOccluded(isOccluded);
reset(true /* hideBouncerWhenShowing */);
- });
+ };
+ if (mCentralSurfaces.isDismissingShadeForActivityLaunch()) {
+ // When isDismissingShadeForActivityLaunch() is true, we know for sure that the
+ // post collapse runnables will be run.
+ mShadeController.get().addPostCollapseAction(postCollapseAction);
+ } else {
+ postCollapseAction.run();
+ }
return;
}
} else if (isShowing && isUnOccluding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/DeviceBasedSatelliteInputLog.kt
similarity index 74%
copy from packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
copy to packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/DeviceBasedSatelliteInputLog.kt
index 252945f..73c015d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/DeviceBasedSatelliteInputLog.kt
@@ -16,11 +16,14 @@
package com.android.systemui.statusbar.pipeline.dagger
-import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
import javax.inject.Qualifier
-/** Detailed [DeviceBasedSatelliteRepository] logs */
+/**
+ * Logs for device-based satellite events that are **not** that frequent/chatty.
+ *
+ * For chatty logs, use [VerboseDeviceBasedSatelliteInputLog] instead.
+ */
@Qualifier
@MustBeDocumented
-@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
-annotation class OemSatelliteInputLog
+@Retention(AnnotationRetention.RUNTIME)
+annotation class DeviceBasedSatelliteInputLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index 88ca9e5..a81bfa4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -227,9 +227,16 @@
@Provides
@SysUISingleton
- @OemSatelliteInputLog
- fun provideOemSatelliteInputLog(factory: LogBufferFactory): LogBuffer {
- return factory.create("DeviceBasedSatelliteInputLog", 150)
+ @DeviceBasedSatelliteInputLog
+ fun provideDeviceBasedSatelliteInputLog(factory: LogBufferFactory): LogBuffer {
+ return factory.create("DeviceBasedSatelliteInputLog", 200)
+ }
+
+ @Provides
+ @SysUISingleton
+ @VerboseDeviceBasedSatelliteInputLog
+ fun provideVerboseDeviceBasedSatelliteInputLog(factory: LogBufferFactory): LogBuffer {
+ return factory.create("VerboseDeviceBasedSatelliteInputLog", 200)
}
const val FIRST_MOBILE_SUB_SHOWING_NETWORK_TYPE_ICON =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/VerboseDeviceBasedSatelliteInputLog.kt
similarity index 75%
rename from packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/VerboseDeviceBasedSatelliteInputLog.kt
index 252945f..af68055 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/OemSatelliteInputLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/VerboseDeviceBasedSatelliteInputLog.kt
@@ -16,11 +16,14 @@
package com.android.systemui.statusbar.pipeline.dagger
-import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
import javax.inject.Qualifier
-/** Detailed [DeviceBasedSatelliteRepository] logs */
+/**
+ * Logs for device-based satellite events that are frequent/chatty.
+ *
+ * For non-chatty logs, use [DeviceBasedSatelliteInputLog] instead.
+ */
@Qualifier
@MustBeDocumented
-@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
-annotation class OemSatelliteInputLog
+@Retention(AnnotationRetention.RUNTIME)
+annotation class VerboseDeviceBasedSatelliteInputLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
index 9d9cc2a..4325897 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
@@ -32,7 +32,8 @@
import com.android.systemui.log.core.LogLevel
import com.android.systemui.log.core.MessageInitializer
import com.android.systemui.log.core.MessagePrinter
-import com.android.systemui.statusbar.pipeline.dagger.OemSatelliteInputLog
+import com.android.systemui.statusbar.pipeline.dagger.DeviceBasedSatelliteInputLog
+import com.android.systemui.statusbar.pipeline.dagger.VerboseDeviceBasedSatelliteInputLog
import com.android.systemui.statusbar.pipeline.satellite.data.RealDeviceBasedSatelliteRepository
import com.android.systemui.statusbar.pipeline.satellite.data.prod.SatelliteSupport.Companion.whenSupported
import com.android.systemui.statusbar.pipeline.satellite.data.prod.SatelliteSupport.NotSupported
@@ -147,7 +148,8 @@
telephonyManager: TelephonyManager,
@Background private val bgDispatcher: CoroutineDispatcher,
@Application private val scope: CoroutineScope,
- @OemSatelliteInputLog private val logBuffer: LogBuffer,
+ @DeviceBasedSatelliteInputLog private val logBuffer: LogBuffer,
+ @VerboseDeviceBasedSatelliteInputLog private val verboseLogBuffer: LogBuffer,
private val systemClock: SystemClock,
) : RealDeviceBasedSatelliteRepository {
@@ -310,7 +312,7 @@
private fun signalStrengthFlow(sm: SupportedSatelliteManager) =
conflatedCallbackFlow {
val cb = NtnSignalStrengthCallback { signalStrength ->
- logBuffer.i({ int1 = signalStrength.level }) {
+ verboseLogBuffer.i({ int1 = signalStrength.level }) {
"onNtnSignalStrengthChanged: level=$int1"
}
trySend(signalStrength.level)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
index 5b954b2..b66ace6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
@@ -21,7 +21,7 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
-import com.android.systemui.statusbar.pipeline.dagger.OemSatelliteInputLog
+import com.android.systemui.statusbar.pipeline.dagger.DeviceBasedSatelliteInputLog
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
@@ -48,7 +48,7 @@
deviceProvisioningInteractor: DeviceProvisioningInteractor,
wifiInteractor: WifiInteractor,
@Application scope: CoroutineScope,
- @OemSatelliteInputLog private val logBuffer: LogBuffer,
+ @DeviceBasedSatelliteInputLog private val logBuffer: LogBuffer,
) {
/** Must be observed by any UI showing Satellite iconography */
val isSatelliteAllowed =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
index d76fd40..0ed1b9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
@@ -24,7 +24,7 @@
import com.android.systemui.log.core.LogLevel
import com.android.systemui.res.R
import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.dagger.OemSatelliteInputLog
+import com.android.systemui.statusbar.pipeline.dagger.DeviceBasedSatelliteInputLog
import com.android.systemui.statusbar.pipeline.satellite.domain.interactor.DeviceBasedSatelliteInteractor
import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
import com.android.systemui.statusbar.pipeline.satellite.ui.model.SatelliteIconModel
@@ -70,7 +70,7 @@
interactor: DeviceBasedSatelliteInteractor,
@Application scope: CoroutineScope,
airplaneModeRepository: AirplaneModeRepository,
- @OemSatelliteInputLog logBuffer: LogBuffer,
+ @DeviceBasedSatelliteInputLog logBuffer: LogBuffer,
) : DeviceBasedSatelliteViewModel {
private val shouldShowIcon: Flow<Boolean> =
interactor.areAllConnectionsOutOfService.flatMapLatest { allOos ->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
index 8b48bd3..2169154 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
@@ -79,7 +79,8 @@
runnable.run()
return
}
- val fn = "[$label] => AvalancheController.update [${getKey(entry)}]"
+ log { "\n "}
+ val fn = "$label => AvalancheController.update ${getKey(entry)}"
if (entry == null) {
log { "Entry is NULL, stop update." }
return
@@ -88,13 +89,13 @@
debugRunnableLabelMap[runnable] = label
}
if (isShowing(entry)) {
- log { "\n$fn => [update showing]" }
+ log { "\n$fn => update showing" }
runnable.run()
} else if (entry in nextMap) {
- log { "\n$fn => [update next]" }
+ log { "\n$fn => update next" }
nextMap[entry]?.add(runnable)
} else if (headsUpEntryShowing == null) {
- log { "\n$fn => [showNow]" }
+ log { "\n$fn => showNow" }
showNow(entry, arrayListOf(runnable))
} else {
// Clean up invalid state when entry is in list but not map and vice versa
@@ -133,20 +134,22 @@
runnable.run()
return
}
- val fn = "[$label] => AvalancheController.delete " + getKey(entry)
+ log { "\n "}
+ val fn = "$label => AvalancheController.delete " + getKey(entry)
if (entry == null) {
- log { "$fn => cannot remove NULL entry" }
+ log { "$fn => entry NULL, running runnable" }
+ runnable.run()
return
}
if (entry in nextMap) {
- log { "$fn => [remove from next]" }
+ log { "$fn => remove from next" }
if (entry in nextMap) nextMap.remove(entry)
if (entry in nextList) nextList.remove(entry)
} else if (entry in debugDropSet) {
- log { "$fn => [remove from dropset]" }
+ log { "$fn => remove from dropset" }
debugDropSet.remove(entry)
} else if (isShowing(entry)) {
- log { "$fn => [remove showing ${getKey(entry)}]" }
+ log { "$fn => remove showing ${getKey(entry)}" }
previousHunKey = getKey(headsUpEntryShowing)
// Show the next HUN before removing this one, so that we don't tell listeners
// onHeadsUpPinnedModeChanged, which causes
@@ -155,7 +158,7 @@
showNext()
runnable.run()
} else {
- log { "$fn => [removing untracked ${getKey(entry)}]" }
+ log { "$fn => removing untracked ${getKey(entry)}" }
}
logState("after $fn")
}
@@ -239,6 +242,18 @@
return keyList
}
+ fun getWaitingEntry(key: String): HeadsUpEntry? {
+ if (!NotificationThrottleHun.isEnabled) {
+ return null
+ }
+ for (headsUpEntry in nextMap.keys) {
+ if (headsUpEntry.mEntry?.key.equals(key)) {
+ return headsUpEntry
+ }
+ }
+ return null
+ }
+
private fun isShowing(entry: HeadsUpEntry): Boolean {
return headsUpEntryShowing != null && entry.mEntry?.key == headsUpEntryShowing?.mEntry?.key
}
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 a7fe49b..2ee98bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
@@ -195,26 +195,29 @@
*/
@Override
public boolean removeNotification(@NonNull String key, boolean releaseImmediately) {
- mLogger.logRemoveNotification(key, releaseImmediately);
+ final boolean isWaiting = mAvalancheController.isWaiting(key);
+ mLogger.logRemoveNotification(key, releaseImmediately, isWaiting);
if (mAvalancheController.isWaiting(key)) {
- removeEntry(key);
+ removeEntry(key, "removeNotification (isWaiting)");
return true;
}
HeadsUpEntry headsUpEntry = mHeadsUpEntryMap.get(key);
if (headsUpEntry == null) {
return true;
}
- if (releaseImmediately || canRemoveImmediately(key)) {
- removeEntry(key);
- } else {
- headsUpEntry.removeAsSoonAsPossible();
- return false;
+ if (releaseImmediately) {
+ removeEntry(key, "removeNotification (releaseImmediately)");
+ return true;
}
- return true;
+ if (canRemoveImmediately(key)) {
+ removeEntry(key, "removeNotification (canRemoveImmediately)");
+ return true;
+ }
+ headsUpEntry.removeAsSoonAsPossible();
+ return false;
}
-
/**
* Called when the notification state has been updated.
* @param key the key of the entry that was updated
@@ -245,7 +248,8 @@
if (shouldHeadsUpAgain) {
headsUpEntry.updateEntry(true /* updatePostTime */, "updateNotification");
if (headsUpEntry != null) {
- setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUpEntry.mEntry));
+ setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUpEntry.mEntry),
+ "updateNotificationInternal");
}
}
}
@@ -264,10 +268,10 @@
List<String> waitingKeysToRemove = mAvalancheController.getWaitingKeys();
for (String key : keysToRemove) {
- removeEntry(key);
+ removeEntry(key, "releaseAllImmediately (keysToRemove)");
}
for (String key : waitingKeysToRemove) {
- removeEntry(key);
+ removeEntry(key, "releaseAllImmediately (waitingKeysToRemove)");
}
}
@@ -338,8 +342,9 @@
}
protected void setEntryPinned(
- @NonNull BaseHeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned) {
- mLogger.logSetEntryPinned(headsUpEntry.mEntry, isPinned);
+ @NonNull BaseHeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned,
+ String reason) {
+ mLogger.logSetEntryPinned(headsUpEntry.mEntry, isPinned, reason);
NotificationEntry entry = headsUpEntry.mEntry;
if (!isPinned) {
headsUpEntry.mWasUnpinned = true;
@@ -376,7 +381,7 @@
entry.setHeadsUp(true);
final boolean shouldPin = shouldHeadsUpBecomePinned(entry);
- setEntryPinned(headsUpEntry, shouldPin);
+ setEntryPinned(headsUpEntry, shouldPin, "onEntryAdded");
EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 1 /* visible */);
for (OnHeadsUpChangedListener listener : mListeners) {
listener.onHeadsUpStateChanged(entry, true);
@@ -387,17 +392,24 @@
* Remove a notification from the alerting entries.
* @param key key of notification to remove
*/
- protected final void removeEntry(@NonNull String key) {
+ protected final void removeEntry(@NonNull String key, String reason) {
HeadsUpEntry headsUpEntry = mHeadsUpEntryMap.get(key);
- mLogger.logRemoveEntryRequest(key);
-
+ boolean isWaiting;
+ if (headsUpEntry == null) {
+ headsUpEntry = mAvalancheController.getWaitingEntry(key);
+ isWaiting = true;
+ } else {
+ isWaiting = false;
+ }
+ mLogger.logRemoveEntryRequest(key, reason, isWaiting);
+ HeadsUpEntry finalHeadsUpEntry = headsUpEntry;
Runnable runnable = () -> {
- mLogger.logRemoveEntry(key);
+ mLogger.logRemoveEntry(key, reason, isWaiting);
- if (headsUpEntry == null) {
+ if (finalHeadsUpEntry == null) {
return;
}
- NotificationEntry entry = headsUpEntry.mEntry;
+ NotificationEntry entry = finalHeadsUpEntry.mEntry;
// If the notification is animating, we will remove it at the end of the animation.
if (entry != null && entry.isExpandAnimationRunning()) {
@@ -405,13 +417,13 @@
}
entry.demoteStickyHun();
mHeadsUpEntryMap.remove(key);
- onEntryRemoved(headsUpEntry);
+ onEntryRemoved(finalHeadsUpEntry);
// TODO(b/328390331) move accessibility events to the view layer
entry.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
if (NotificationsHeadsUpRefactor.isEnabled()) {
- headsUpEntry.cancelAutoRemovalCallbacks("removeEntry");
+ finalHeadsUpEntry.cancelAutoRemovalCallbacks("removeEntry");
} else {
- headsUpEntry.reset();
+ finalHeadsUpEntry.reset();
}
};
mAvalancheController.delete(headsUpEntry, runnable, "removeEntry");
@@ -424,7 +436,7 @@
protected void onEntryRemoved(HeadsUpEntry headsUpEntry) {
NotificationEntry entry = headsUpEntry.mEntry;
entry.setHeadsUp(false);
- setEntryPinned(headsUpEntry, false /* isPinned */);
+ setEntryPinned(headsUpEntry, false /* isPinned */, "onEntryRemoved");
EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 0 /* visible */);
mLogger.logNotificationActuallyRemoved(entry);
for (OnHeadsUpChangedListener listener : mListeners) {
@@ -584,7 +596,7 @@
Runnable runnable = () -> {
mLogger.logUnpinEntry(key);
- setEntryPinned(headsUpEntry, false /* isPinned */);
+ setEntryPinned(headsUpEntry, false /* isPinned */, "unpinAll");
// maybe it got un sticky
headsUpEntry.updateEntry(false /* updatePostTime */, "unpinAll");
@@ -985,7 +997,7 @@
/** Creates a runnable to remove this notification from the alerting entries. */
protected Runnable createRemoveRunnable(NotificationEntry entry) {
- return () -> removeEntry(entry.getKey());
+ return () -> removeEntry(entry.getKey(), "createRemoveRunnable");
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
index 11cbc9c..6ffb162 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
@@ -121,19 +121,23 @@
})
}
- fun logRemoveEntryRequest(key: String) {
+ fun logRemoveEntryRequest(key: String, reason: String, isWaiting: Boolean) {
buffer.log(TAG, INFO, {
str1 = logKey(key)
+ str2 = reason
+ bool1 = isWaiting
}, {
- "request: remove entry $str1"
+ "request: $str2 => remove entry $str1 isWaiting: $isWaiting"
})
}
- fun logRemoveEntry(key: String) {
+ fun logRemoveEntry(key: String, reason: String, isWaiting: Boolean) {
buffer.log(TAG, INFO, {
str1 = logKey(key)
+ str2 = reason
+ bool1 = isWaiting
}, {
- "remove entry $str1"
+ "$str2 => remove entry $str1 isWaiting: $isWaiting"
})
}
@@ -153,12 +157,13 @@
})
}
- fun logRemoveNotification(key: String, releaseImmediately: Boolean) {
+ fun logRemoveNotification(key: String, releaseImmediately: Boolean, isWaiting: Boolean) {
buffer.log(TAG, INFO, {
str1 = logKey(key)
bool1 = releaseImmediately
+ bool2 = isWaiting
}, {
- "remove notification $str1 releaseImmediately: $bool1"
+ "remove notification $str1 releaseImmediately: $bool1 isWaiting: $bool2"
})
}
@@ -208,12 +213,13 @@
})
}
- fun logSetEntryPinned(entry: NotificationEntry, isPinned: Boolean) {
+ fun logSetEntryPinned(entry: NotificationEntry, isPinned: Boolean, reason: String) {
buffer.log(TAG, VERBOSE, {
str1 = entry.logKey
bool1 = isPinned
+ str2 = reason
}, {
- "set entry pinned $str1 pinned: $bool1"
+ "$str2 => set entry pinned $str1 pinned: $bool1"
})
}
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 f4fc978..1ae5614 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.dagger
+import android.content.ContentResolver
import android.content.Context
import android.media.AudioManager
import com.android.settingslib.bluetooth.LocalBluetoothManager
@@ -28,6 +29,7 @@
import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor
import com.android.settingslib.volume.shared.AudioManagerEventsReceiver
import com.android.settingslib.volume.shared.AudioManagerEventsReceiverImpl
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import dagger.Module
@@ -42,21 +44,31 @@
companion object {
@Provides
+ @SysUISingleton
fun provideAudioManagerIntentsReceiver(
@Application context: Context,
@Application coroutineScope: CoroutineScope,
): AudioManagerEventsReceiver = AudioManagerEventsReceiverImpl(context, coroutineScope)
@Provides
+ @SysUISingleton
fun provideAudioRepository(
intentsReceiver: AudioManagerEventsReceiver,
audioManager: AudioManager,
+ contentResolver: ContentResolver,
@Background coroutineContext: CoroutineContext,
@Application coroutineScope: CoroutineScope,
): AudioRepository =
- AudioRepositoryImpl(intentsReceiver, audioManager, coroutineContext, coroutineScope)
+ AudioRepositoryImpl(
+ intentsReceiver,
+ audioManager,
+ contentResolver,
+ coroutineContext,
+ coroutineScope,
+ )
@Provides
+ @SysUISingleton
fun provideAudioSharingRepository(
localBluetoothManager: LocalBluetoothManager?,
@Background coroutineContext: CoroutineContext,
@@ -64,10 +76,12 @@
AudioSharingRepositoryImpl(localBluetoothManager, coroutineContext)
@Provides
+ @SysUISingleton
fun provideAudioModeInteractor(repository: AudioRepository): AudioModeInteractor =
AudioModeInteractor(repository)
@Provides
+ @SysUISingleton
fun provideAudioVolumeInteractor(
audioRepository: AudioRepository,
notificationsSoundPolicyInteractor: NotificationsSoundPolicyInteractor,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/CaptioningModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/CaptioningModule.kt
index ea67eea..73f5237 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/CaptioningModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/CaptioningModule.kt
@@ -20,6 +20,7 @@
import com.android.settingslib.view.accessibility.data.repository.CaptioningRepository
import com.android.settingslib.view.accessibility.data.repository.CaptioningRepositoryImpl
import com.android.settingslib.view.accessibility.domain.interactor.CaptioningInteractor
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import dagger.Module
@@ -33,6 +34,7 @@
companion object {
@Provides
+ @SysUISingleton
fun provideCaptioningRepository(
captioningManager: CaptioningManager,
@Background coroutineContext: CoroutineContext,
@@ -41,6 +43,7 @@
CaptioningRepositoryImpl(captioningManager, coroutineContext, coroutineScope)
@Provides
+ @SysUISingleton
fun provideCaptioningInteractor(repository: CaptioningRepository): CaptioningInteractor =
CaptioningInteractor(repository)
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt
index 3696108..efab199 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/MediaDevicesModule.kt
@@ -18,7 +18,6 @@
import android.media.session.MediaSessionManager
import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.volume.data.repository.LocalMediaRepository
import com.android.settingslib.volume.data.repository.MediaControllerRepository
import com.android.settingslib.volume.data.repository.MediaControllerRepositoryImpl
import com.android.settingslib.volume.shared.AudioManagerEventsReceiver
@@ -52,12 +51,6 @@
@Provides
@SysUISingleton
- fun provideLocalMediaRepository(
- factory: LocalMediaRepositoryFactory
- ): LocalMediaRepository = factory.create(null)
-
- @Provides
- @SysUISingleton
fun provideMediaDeviceSessionRepository(
intentsReceiver: AudioManagerEventsReceiver,
mediaSessionManager: MediaSessionManager,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/SpatializerModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/SpatializerModule.kt
index 4ba7cbb..a11997a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/SpatializerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/SpatializerModule.kt
@@ -21,6 +21,7 @@
import com.android.settingslib.media.data.repository.SpatializerRepository
import com.android.settingslib.media.data.repository.SpatializerRepositoryImpl
import com.android.settingslib.media.domain.interactor.SpatializerInteractor
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import dagger.Module
import dagger.Provides
@@ -33,17 +34,20 @@
companion object {
@Provides
+ @SysUISingleton
fun provideSpatializer(
audioManager: AudioManager,
): Spatializer = audioManager.spatializer
@Provides
+ @SysUISingleton
fun provdieSpatializerRepository(
spatializer: Spatializer,
@Background backgroundContext: CoroutineContext,
): SpatializerRepository = SpatializerRepositoryImpl(spatializer, backgroundContext)
@Provides
+ @SysUISingleton
fun provideSpatializerInetractor(repository: SpatializerRepository): SpatializerInteractor =
SpatializerInteractor(repository)
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt
index e052f24..0dc2647 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/data/repository/LocalMediaRepositoryFactory.kt
@@ -18,6 +18,7 @@
import com.android.settingslib.volume.data.repository.LocalMediaRepository
import com.android.settingslib.volume.data.repository.LocalMediaRepositoryImpl
import com.android.settingslib.volume.shared.AudioManagerEventsReceiver
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.media.controls.util.LocalMediaManagerFactory
import javax.inject.Inject
@@ -28,6 +29,7 @@
fun create(packageName: String?): LocalMediaRepository
}
+@SysUISingleton
class LocalMediaRepositoryFactoryImpl
@Inject
constructor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
index 593cfde..bfc7775 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
@@ -39,7 +39,7 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -122,7 +122,7 @@
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testTransitionToGlanceableHub_onWakeup_ifIdleOnCommunal_noOccludingActivity() =
testScope.runTest {
- kosmos.fakeCommunalRepository.setTransitionState(
+ kosmos.fakeCommunalSceneRepository.setTransitionState(
flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
)
runCurrent()
@@ -158,7 +158,7 @@
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testTransitionToOccluded_onWakeup_whenOccludingActivityOnTop_evenIfIdleOnCommunal() =
testScope.runTest {
- kosmos.fakeCommunalRepository.setTransitionState(
+ kosmos.fakeCommunalSceneRepository.setTransitionState(
flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
)
runCurrent()
@@ -177,6 +177,7 @@
@Test
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ @Suppress("ktlint:standard:max-line-length")
fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetected_fromAod_nonDismissableKeyguard() =
testScope.runTest {
powerInteractor.onCameraLaunchGestureDetected()
@@ -241,6 +242,7 @@
@Test
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+ @Suppress("ktlint:standard:max-line-length")
fun testTransitionToOccluded_onWakeUp_ifPowerButtonGestureDetectedAfterFinishedInAod_fromGone() =
testScope.runTest {
powerInteractor.setAwakeForTest()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt
index d3c4848..65aa825 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt
@@ -38,7 +38,7 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -110,7 +110,7 @@
@EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testShowWhenLockedActivity_noLongerOnTop_transitionsToGlanceableHub_ifIdleOnCommunal() =
testScope.runTest {
- kosmos.fakeCommunalRepository.setTransitionState(
+ kosmos.fakeCommunalSceneRepository.setTransitionState(
flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
index 1839d8d..14f2d65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
@@ -23,7 +23,7 @@
import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -170,7 +170,7 @@
fun testReturnToGlanceableHub_whenBouncerHides_ifIdleOnCommunal() =
testScope.runTest {
underTest.start()
- kosmos.fakeCommunalRepository.setTransitionState(
+ kosmos.fakeCommunalSceneRepository.setTransitionState(
flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
)
bouncerRepository.setPrimaryShow(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index fa3fe5c..e02fb29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -30,6 +30,7 @@
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.dock.fakeDockManager
import com.android.systemui.flags.BrokenWithSceneContainer
import com.android.systemui.flags.DisableSceneContainer
@@ -511,7 +512,6 @@
.startedTransition(
to = KeyguardState.LOCKSCREEN,
from = KeyguardState.DOZING,
- ownerName = "FromDozingTransitionInteractor",
animatorAssertion = { it.isNotNull() }
)
@@ -600,7 +600,6 @@
.startedTransition(
to = KeyguardState.PRIMARY_BOUNCER,
from = KeyguardState.DOZING,
- ownerName = "FromDozingTransitionInteractor",
animatorAssertion = { it.isNotNull() }
)
@@ -618,6 +617,7 @@
// WHEN the device wakes up without a keyguard
keyguardRepository.setKeyguardShowing(false)
keyguardRepository.setKeyguardDismissible(true)
+ kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(false)
powerInteractor.setAwakeForTest()
advanceTimeBy(60L)
@@ -625,7 +625,6 @@
.startedTransition(
to = KeyguardState.GONE,
from = KeyguardState.DOZING,
- ownerName = "FromDozingTransitionInteractor",
animatorAssertion = { it.isNotNull() }
)
@@ -683,7 +682,6 @@
.startedTransition(
to = KeyguardState.GLANCEABLE_HUB,
from = KeyguardState.DOZING,
- ownerName = FromDozingTransitionInteractor::class.simpleName,
animatorAssertion = { it.isNotNull() }
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionManagerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionManagerRepositoryTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
index 6043ede..ef73e2e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/data/repository/MediaProjectionManagerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 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,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.mediaprojection.taskswitcher.data.repository
+package com.android.systemui.mediaprojection.data.repository
import android.os.Binder
import android.testing.AndroidTestingRunner
@@ -23,9 +23,9 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createToken
-import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.taskswitcher.fakeActivityTaskManager
import com.android.systemui.mediaprojection.taskswitcher.fakeMediaProjectionManager
import com.android.systemui.mediaprojection.taskswitcher.mediaProjectionManagerRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
index 9382c58..ad18099 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt
@@ -40,6 +40,7 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
@RunWith(AndroidTestingRunner::class)
@@ -66,6 +67,10 @@
fakeBroadcastDispatcher,
)
coordinator.start()
+ // When the coordinator starts up, the view model will immediately emit a NotShowing event
+ // and hide the notification. That's fine, but we should reset the notification manager so
+ // that the initial emission isn't part of the tests.
+ reset(notificationManager)
}
@Test
@@ -82,8 +87,13 @@
@Test
fun hideNotification() {
testScope.runTest {
+ // First, show a notification
+ switchTask()
+
+ // WHEN the projection is stopped
fakeMediaProjectionManager.dispatchOnStop()
+ // THEN the notification is hidden
verify(notificationManager).cancel(any(), any())
}
}
@@ -91,14 +101,16 @@
@Test
fun notificationIdIsConsistent() {
testScope.runTest {
- fakeMediaProjectionManager.dispatchOnStop()
- val idCancel = argumentCaptor<Int>()
- verify(notificationManager).cancel(any(), idCancel.capture())
-
+ // First, show a notification
switchTask()
val idNotify = argumentCaptor<Int>()
verify(notificationManager).notify(any(), idNotify.capture(), any())
+ // Then, hide the notification
+ fakeMediaProjectionManager.dispatchOnStop()
+ val idCancel = argumentCaptor<Int>()
+ verify(notificationManager).cancel(any(), idCancel.capture())
+
assertEquals(idCancel.value, idNotify.value)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
new file mode 100644
index 0000000..07ec38e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
@@ -0,0 +1,300 @@
+/*
+ * 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
+
+import android.content.res.Configuration
+import android.content.res.Resources
+import android.testing.TestableLooper.RunWithLooper
+import android.view.ViewTreeObserver
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.haptics.qs.QSLongPressEffect
+import com.android.systemui.haptics.qs.qsLongPressEffect
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.InstantTaskExecutorRule
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.qs.customize.QSCustomizerController
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.statusbar.policy.SplitShadeStateController
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import javax.inject.Provider
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RunWithLooper
+@OptIn(ExperimentalCoroutinesApi::class)
+@EnableSceneContainer
+class QSPanelControllerBaseSceneContainerTest : SysuiTestCase() {
+
+ @Rule @JvmField val mInstantTaskExecutor = InstantTaskExecutorRule()
+
+ private val kosmos = testKosmos()
+
+ @Mock private lateinit var qsPanel: QSPanel
+ @Mock private lateinit var qsHost: QSHost
+ @Mock private lateinit var qsCustomizerController: QSCustomizerController
+ @Mock private lateinit var metricsLogger: MetricsLogger
+ private val uiEventLogger = UiEventLoggerFake()
+ @Mock private lateinit var qsLogger: QSLogger
+ private val dumpManager = DumpManager()
+ @Mock private lateinit var tileLayout: PagedTileLayout
+ @Mock private lateinit var resources: Resources
+ private val configuration = Configuration()
+ @Mock private lateinit var viewTreeObserver: ViewTreeObserver
+ @Mock private lateinit var mediaHost: MediaHost
+
+ private var isSplitShade = false
+ private val splitShadeStateController =
+ object : SplitShadeStateController {
+ override fun shouldUseSplitNotificationShade(resources: Resources): Boolean {
+ return isSplitShade
+ }
+ }
+ private val longPressEffectProvider: Provider<QSLongPressEffect> = Provider {
+ kosmos.qsLongPressEffect
+ }
+
+ private val mediaVisible = MutableStateFlow(false)
+
+ private lateinit var underTest: TestableQSPanelControllerBase
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ allowTestableLooperAsMainThread()
+ Dispatchers.setMain(kosmos.testDispatcher)
+
+ whenever(qsPanel.isAttachedToWindow).thenReturn(true)
+ whenever(qsPanel.orCreateTileLayout).thenReturn(tileLayout)
+ whenever(qsPanel.tileLayout).thenReturn(tileLayout)
+ whenever(qsPanel.resources).thenReturn(resources)
+ whenever(qsPanel.viewTreeObserver).thenReturn(viewTreeObserver)
+ whenever(qsHost.tiles).thenReturn(emptyList())
+ whenever(resources.configuration).thenReturn(configuration)
+
+ underTest = createUnderTest()
+ underTest.init()
+ }
+
+ @After
+ fun tearDown() {
+ disallowTestableLooperAsMainThread()
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun configurationChange_onlySplitShadeConfigChanges_horizontalInSceneUpdated() =
+ with(kosmos) {
+ testScope.runTest {
+ clearInvocations(qsPanel)
+
+ mediaVisible.value = true
+ runCurrent()
+ isSplitShade = false
+ configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+ configuration.screenLayout = Configuration.SCREENLAYOUT_LONG_YES
+ underTest.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+
+ assertThat(underTest.shouldUseHorizontalInScene()).isTrue()
+ verify(qsPanel).setColumnRowLayout(true)
+ clearInvocations(qsPanel)
+
+ isSplitShade = true
+ underTest.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+
+ assertThat(underTest.shouldUseHorizontalInScene()).isFalse()
+ verify(qsPanel).setColumnRowLayout(false)
+ }
+ }
+
+ @Test
+ fun configurationChange_shouldUseHorizontalInSceneInLongDevices() =
+ with(kosmos) {
+ testScope.runTest {
+ clearInvocations(qsPanel)
+
+ mediaVisible.value = true
+ runCurrent()
+ isSplitShade = false
+ // When device is rotated to landscape and is long
+ configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+ configuration.screenLayout = Configuration.SCREENLAYOUT_LONG_YES
+ underTest.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+
+ // Then the layout changes
+ assertThat(underTest.shouldUseHorizontalInScene()).isTrue()
+ verify(qsPanel).setColumnRowLayout(true)
+ clearInvocations(qsPanel)
+
+ // When device changes to not-long
+ configuration.screenLayout = Configuration.SCREENLAYOUT_LONG_NO
+ underTest.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+
+ // Then the layout changes back
+ assertThat(underTest.shouldUseHorizontalInScene()).isFalse()
+ verify(qsPanel).setColumnRowLayout(false)
+ }
+ }
+
+ @Test
+ fun configurationChange_horizontalInScene_onlyInLandscape() =
+ with(kosmos) {
+ testScope.runTest {
+ clearInvocations(qsPanel)
+
+ mediaVisible.value = true
+ runCurrent()
+ isSplitShade = false
+
+ // When device is rotated to landscape and is long
+ configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+ configuration.screenLayout = Configuration.SCREENLAYOUT_LONG_YES
+ underTest.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+
+ // Then the layout changes
+ assertThat(underTest.shouldUseHorizontalInScene()).isTrue()
+ verify(qsPanel).setColumnRowLayout(true)
+ clearInvocations(qsPanel)
+
+ // When it is rotated back to portrait
+ configuration.orientation = Configuration.ORIENTATION_PORTRAIT
+ underTest.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+
+ // Then the layout changes back
+ assertThat(underTest.shouldUseHorizontalInScene()).isFalse()
+ verify(qsPanel).setColumnRowLayout(false)
+ }
+ }
+
+ @Test
+ fun changeMediaVisible_changesHorizontalInScene() =
+ with(kosmos) {
+ testScope.runTest {
+ mediaVisible.value = false
+ runCurrent()
+ isSplitShade = false
+ configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+ configuration.screenLayout = Configuration.SCREENLAYOUT_LONG_YES
+ underTest.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+
+ assertThat(underTest.shouldUseHorizontalInScene()).isFalse()
+ clearInvocations(qsPanel)
+
+ mediaVisible.value = true
+ runCurrent()
+
+ assertThat(underTest.shouldUseHorizontalInScene()).isTrue()
+ verify(qsPanel).setColumnRowLayout(true)
+ }
+ }
+
+ @Test
+ fun startFromMediaHorizontalLong_shouldUseHorizontal() =
+ with(kosmos) {
+ testScope.runTest {
+ mediaVisible.value = true
+ runCurrent()
+ isSplitShade = false
+ configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+ configuration.screenLayout = Configuration.SCREENLAYOUT_LONG_YES
+
+ underTest = createUnderTest()
+ underTest.init()
+ runCurrent()
+
+ assertThat(underTest.shouldUseHorizontalInScene()).isTrue()
+ verify(qsPanel).setColumnRowLayout(true)
+ }
+ }
+
+ private fun createUnderTest(): TestableQSPanelControllerBase {
+ return TestableQSPanelControllerBase(
+ qsPanel,
+ qsHost,
+ qsCustomizerController,
+ mediaHost,
+ metricsLogger,
+ uiEventLogger,
+ qsLogger,
+ dumpManager,
+ splitShadeStateController,
+ longPressEffectProvider,
+ mediaVisible,
+ )
+ }
+
+ private class TestableQSPanelControllerBase(
+ view: QSPanel,
+ qsHost: QSHost,
+ qsCustomizerController: QSCustomizerController,
+ mediaHost: MediaHost,
+ metricsLogger: MetricsLogger,
+ uiEventLogger: UiEventLogger,
+ qsLogger: QSLogger,
+ dumpManager: DumpManager,
+ splitShadeStateController: SplitShadeStateController,
+ longPressEffectProvider: Provider<QSLongPressEffect>,
+ private val mediaVisibleFlow: StateFlow<Boolean>
+ ) :
+ QSPanelControllerBase<QSPanel>(
+ view,
+ qsHost,
+ qsCustomizerController,
+ /* usingMediaPlayer= */ false,
+ mediaHost,
+ metricsLogger,
+ uiEventLogger,
+ qsLogger,
+ dumpManager,
+ splitShadeStateController,
+ longPressEffectProvider
+ ) {
+
+ init {
+ whenever(view.dumpableTag).thenReturn(hashCode().toString())
+ }
+ override fun getMediaVisibleFlow(): StateFlow<Boolean> {
+ return mediaVisibleFlow
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index 542bfaa..225adab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -17,9 +17,13 @@
package com.android.systemui.qs;
import static com.android.systemui.Flags.FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS;
+import static com.android.systemui.flags.SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag;
import static com.google.common.truth.Truth.assertThat;
+import static kotlinx.coroutines.flow.FlowKt.asStateFlow;
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -37,9 +41,10 @@
import android.content.res.Resources;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.testing.TestableLooper.RunWithLooper;
import android.view.ContextThemeWrapper;
+import android.view.ViewTreeObserver;
import androidx.test.filters.SmallTest;
@@ -49,18 +54,26 @@
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.DisableSceneContainer;
import com.android.systemui.haptics.qs.QSLongPressEffect;
import com.android.systemui.kosmos.KosmosJavaAdapter;
+import com.android.systemui.lifecycle.InstantTaskExecutorRule;
import com.android.systemui.media.controls.ui.view.MediaHost;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.util.animation.DisappearParameters;
+import kotlinx.coroutines.flow.MutableStateFlow;
+import kotlinx.coroutines.flow.StateFlow;
+
+import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -73,11 +86,22 @@
import javax.inject.Provider;
-@RunWith(AndroidTestingRunner.class)
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@RunWithLooper
@SmallTest
public class QSPanelControllerBaseTest extends SysuiTestCase {
+ @Rule
+ public final InstantTaskExecutorRule mInstantTaskExecutor = new InstantTaskExecutorRule();
+
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return parameterizeSceneContainerFlag();
+ }
+
private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
@Mock
private QSPanel mQSPanel;
@@ -109,10 +133,13 @@
Configuration mConfiguration;
@Mock
Runnable mHorizontalLayoutListener;
+ @Mock
+ private ViewTreeObserver mViewTreeObserver;
+
private TestableLongPressEffectProvider mLongPressEffectProvider =
new TestableLongPressEffectProvider();
- private QSPanelControllerBase<QSPanel> mController;
+ private TestableQSPanelControllerBase mController;
/** Implementation needed to ensure we have a reflectively-available class name. */
private class TestableQSPanelControllerBase extends QSPanelControllerBase<QSPanel> {
@@ -120,15 +147,27 @@
QSCustomizerController qsCustomizerController, MediaHost mediaHost,
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
DumpManager dumpManager) {
- super(view, host, qsCustomizerController, true, mediaHost, metricsLogger, uiEventLogger,
+ super(view, host, qsCustomizerController, usingMediaPlayer(),
+ mediaHost, metricsLogger, uiEventLogger,
qsLogger, dumpManager, new ResourcesSplitShadeStateController(),
mLongPressEffectProvider);
}
+ private MutableStateFlow<Boolean> mMediaVisible = MutableStateFlow(false);
+
@Override
protected QSTileRevealController createTileRevealController() {
return mQSTileRevealController;
}
+
+ @Override
+ StateFlow<Boolean> getMediaVisibleFlow() {
+ return asStateFlow(mMediaVisible);
+ }
+
+ void setMediaVisible(boolean visible) {
+ mMediaVisible.tryEmit(visible);
+ }
}
private class TestableLongPressEffectProvider implements Provider<QSLongPressEffect> {
@@ -142,16 +181,24 @@
}
}
+ public QSPanelControllerBaseTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
+ allowTestableLooperAsMainThread();
+
when(mQSPanel.isAttachedToWindow()).thenReturn(true);
when(mQSPanel.getDumpableTag()).thenReturn("QSPanel");
when(mQSPanel.openPanelEvent()).thenReturn(QSEvent.QS_PANEL_EXPANDED);
when(mQSPanel.closePanelEvent()).thenReturn(QSEvent.QS_PANEL_COLLAPSED);
when(mQSPanel.getOrCreateTileLayout()).thenReturn(mPagedTileLayout);
when(mQSPanel.getTileLayout()).thenReturn(mPagedTileLayout);
+ when(mQSPanel.getViewTreeObserver()).thenReturn(mViewTreeObserver);
when(mQSTile.getTileSpec()).thenReturn("dnd");
when(mQSHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
when(mQSTileRevealControllerFactory.create(any(), any()))
@@ -174,6 +221,11 @@
reset(mQSTileRevealController);
}
+ @After
+ public void tearDown() {
+ disallowTestableLooperAsMainThread();
+ }
+
@Test
public void testSetRevealExpansion_preAttach() {
mController.onViewDetached();
@@ -269,6 +321,7 @@
@Test
+ @DisableSceneContainer
public void testShouldUseHorizontalLayout_falseForSplitShade() {
mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;
mConfiguration.screenLayout = Configuration.SCREENLAYOUT_LONG_YES;
@@ -294,6 +347,7 @@
}
@Test
+ @DisableSceneContainer
public void testChangeConfiguration_shouldUseHorizontalLayoutInLandscape_true() {
when(mMediaHost.getVisible()).thenReturn(true);
mController.setUsingHorizontalLayoutChangeListener(mHorizontalLayoutListener);
@@ -317,6 +371,7 @@
}
@Test
+ @DisableSceneContainer
public void testChangeConfiguration_shouldUseHorizontalLayoutInLongDevices_true() {
when(mMediaHost.getVisible()).thenReturn(true);
mController.setUsingHorizontalLayoutChangeListener(mHorizontalLayoutListener);
@@ -353,6 +408,7 @@
}
@Test
+ @DisableSceneContainer
public void configurationChange_onlySplitShadeConfigChanges_horizontalLayoutStatusUpdated() {
// Preconditions for horizontal layout
when(mMediaHost.getVisible()).thenReturn(true);
@@ -502,4 +558,20 @@
verify(mQSPanel, times(2)).removeTile(any());
verify(mQSPanel, times(2)).addTile(any());
}
+
+ @Test
+ public void dettach_destroy_attach_tilesAreNotReadded() {
+ when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
+ mController.setTiles();
+
+ mController.onViewDetached();
+ mController.destroy();
+ mController.onViewAttached();
+
+ assertThat(mController.mRecords).isEmpty();
+ }
+
+ private boolean usingMediaPlayer() {
+ return !SceneContainerFlag.isEnabled();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index e50320d..545d19d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -10,6 +10,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.haptics.qs.QSLongPressEffect
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.plugins.FalsingManager
@@ -17,6 +18,7 @@
import com.android.systemui.qs.customize.QSCustomizerController
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.settings.brightness.BrightnessController
import com.android.systemui.settings.brightness.BrightnessSliderController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
@@ -63,6 +65,9 @@
@Mock private lateinit var configuration: Configuration
@Mock private lateinit var pagedTileLayout: PagedTileLayout
@Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect>
+ @Mock private lateinit var mediaCarouselInteractor: MediaCarouselInteractor
+
+ private val usingMediaPlayer: Boolean by lazy { !SceneContainerFlag.isEnabled }
private lateinit var controller: QSPanelController
private val testableResources: TestableResources = mContext.orCreateTestableResources
@@ -88,7 +93,7 @@
tunerService,
qsHost,
qsCustomizerController,
- /* usingMediaPlayer= */ true,
+ /* usingMediaPlayer= */ usingMediaPlayer,
mediaHost,
qsTileRevealControllerFactory,
dumpManager,
@@ -101,6 +106,7 @@
statusBarKeyguardViewManager,
ResourcesSplitShadeStateController(),
longPressEffectProvider,
+ mediaCarouselInteractor,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
index 5c6ed70..e2a4d67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
@@ -275,6 +275,19 @@
ViewUtils.detachView(panel)
}
+ @Test
+ fun setRowColumnLayout() {
+ qsPanel.setColumnRowLayout(/* withMedia= */ false)
+
+ assertThat(qsPanel.tileLayout!!.minRows).isEqualTo(1)
+ assertThat(qsPanel.tileLayout!!.maxColumns).isEqualTo(4)
+
+ qsPanel.setColumnRowLayout(/* withMedia= */ true)
+
+ assertThat(qsPanel.tileLayout!!.minRows).isEqualTo(2)
+ assertThat(qsPanel.tileLayout!!.maxColumns).isEqualTo(2)
+ }
+
private infix fun View.isLeftOf(other: View): Boolean {
val rect = Rect()
getBoundsOnScreen(rect)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
index 1eb0a51..fee4b53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
@@ -25,6 +25,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.haptics.qs.QSLongPressEffect
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.plugins.qs.QSTile
@@ -62,6 +63,10 @@
@Mock private lateinit var tileLayout: TileLayout
@Captor private lateinit var captor: ArgumentCaptor<QSPanel.OnConfigurationChangedListener>
@Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect>
+ @Mock private lateinit var mediaCarouselInteractor: MediaCarouselInteractor
+
+ private val usingMediaPlayer: Boolean
+ get() = false
private val uiEventLogger = UiEventLoggerFake()
private val dumpManager = DumpManager()
@@ -86,7 +91,7 @@
quickQSPanel,
qsHost,
qsCustomizerController,
- /* usingMediaPlayer = */ false,
+ usingMediaPlayer,
mediaHost,
{ usingCollapsedLandscapeMedia },
metricsLogger,
@@ -94,6 +99,7 @@
qsLogger,
dumpManager,
longPressEffectProvider,
+ mediaCarouselInteractor,
)
controller.init()
@@ -163,6 +169,7 @@
qsLogger: QSLogger,
dumpManager: DumpManager,
longPressEffectProvider: Provider<QSLongPressEffect>,
+ mediaCarouselInteractor: MediaCarouselInteractor,
) :
QuickQSPanelController(
view,
@@ -177,6 +184,7 @@
dumpManager,
ResourcesSplitShadeStateController(),
longPressEffectProvider,
+ mediaCarouselInteractor
) {
private var rotation = RotationUtils.ROTATION_NONE
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 0ec8552..42b81de 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
@@ -116,6 +116,7 @@
"test_spec:\n" +
" QSTileState(" +
"icon=() -> com.android.systemui.common.shared.model.Icon?, " +
+ "iconRes=null, " +
"label=test_data, " +
"activationState=INACTIVE, " +
"secondaryLabel=null, " +
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt
index 4215b8c..e7bde681 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt
@@ -109,15 +109,10 @@
activationState: QSTileState.ActivationState,
): QSTileState {
val label = testLabel
+ val iconRes = com.android.internal.R.drawable.stat_sys_managed_profile_status
return QSTileState(
- icon = {
- Icon.Loaded(
- context.getDrawable(
- com.android.internal.R.drawable.stat_sys_managed_profile_status
- )!!,
- null
- )
- },
+ icon = { Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+ iconRes = iconRes,
label = label,
activationState = activationState,
secondaryLabel =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index deecc5b..0d7a9e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -146,7 +146,8 @@
@Test
public void testLogStartPartialRecording() {
- MediaProjectionCaptureTarget target = new MediaProjectionCaptureTarget(new LaunchCookie());
+ MediaProjectionCaptureTarget target =
+ new MediaProjectionCaptureTarget(new LaunchCookie(), 12345);
Intent startIntent = RecordingService.getStartIntent(mContext, 0, 0, false, target);
mRecordingService.onStartCommand(startIntent, 0, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
index 896c3bf..6f5c56e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
@@ -21,41 +21,38 @@
import android.os.Process
import android.os.UserHandle
import android.testing.AndroidTestingRunner
-import android.view.accessibility.AccessibilityManager
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
-import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
-import com.android.systemui.util.mockito.argumentCaptor
-import com.android.systemui.util.mockito.capture
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
+import java.util.UUID
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
-import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.runner.RunWith
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
import org.mockito.kotlin.never
+import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@RunWith(AndroidTestingRunner::class)
@SmallTest
class DefaultScreenshotActionsProviderTest : SysuiTestCase() {
private val actionExecutor = mock<ActionExecutor>()
- private val accessibilityManager = mock<AccessibilityManager>()
private val uiEventLogger = mock<UiEventLogger>()
+ private val actionsCallback = mock<ScreenshotActionsController.ActionsCallback>()
private val request = ScreenshotData.forTesting()
private val validResult = ScreenshotSavedResult(Uri.EMPTY, Process.myUserHandle(), 0)
- private lateinit var viewModel: ScreenshotViewModel
private lateinit var actionsProvider: ScreenshotActionsProvider
@Before
fun setUp() {
- viewModel = ScreenshotViewModel(accessibilityManager)
request.userHandle = UserHandle.OWNER
}
@@ -63,8 +60,9 @@
fun previewActionAccessed_beforeScreenshotCompleted_doesNothing() {
actionsProvider = createActionsProvider()
- assertNotNull(viewModel.previewAction.value)
- viewModel.previewAction.value!!.invoke()
+ val previewActionCaptor = argumentCaptor<() -> Unit>()
+ verify(actionsCallback).providePreviewAction(previewActionCaptor.capture())
+ previewActionCaptor.firstValue.invoke()
verifyNoMoreInteractions(actionExecutor)
}
@@ -72,13 +70,13 @@
fun actionButtonsAccessed_beforeScreenshotCompleted_doesNothing() {
actionsProvider = createActionsProvider()
- assertThat(viewModel.actions.value.size).isEqualTo(2)
- val firstAction = viewModel.actions.value[0]
- assertThat(firstAction.onClicked).isNotNull()
- val secondAction = viewModel.actions.value[1]
- assertThat(secondAction.onClicked).isNotNull()
- firstAction.onClicked!!.invoke()
- secondAction.onClicked!!.invoke()
+ val actionButtonCaptor = argumentCaptor<() -> Unit>()
+ verify(actionsCallback, times(2))
+ .provideActionButton(any(), any(), actionButtonCaptor.capture())
+ val firstAction = actionButtonCaptor.firstValue
+ val secondAction = actionButtonCaptor.secondValue
+ firstAction.invoke()
+ secondAction.invoke()
verifyNoMoreInteractions(actionExecutor)
}
@@ -87,29 +85,39 @@
actionsProvider = createActionsProvider()
actionsProvider.setCompletedScreenshot(validResult)
- viewModel.actions.value[0].onClicked!!.invoke()
- verify(uiEventLogger).log(eq(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED), eq(0), eq(""))
+ val actionButtonCaptor = argumentCaptor<() -> Unit>()
+ verify(actionsCallback, times(2))
+ .provideActionButton(any(), any(), actionButtonCaptor.capture())
+ actionButtonCaptor.firstValue.invoke()
+
+ verify(uiEventLogger).log(eq(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED), eq(0), eq(""))
val intentCaptor = argumentCaptor<Intent>()
verify(actionExecutor)
- .startSharedTransition(capture(intentCaptor), eq(Process.myUserHandle()), eq(true))
- assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_EDIT)
+ .startSharedTransition(intentCaptor.capture(), eq(Process.myUserHandle()), eq(false))
+ assertThat(intentCaptor.firstValue.action).isEqualTo(Intent.ACTION_CHOOSER)
}
@Test
fun actionAccessed_whilePending_launchesMostRecentAction() = runTest {
actionsProvider = createActionsProvider()
- viewModel.actions.value[0].onClicked!!.invoke()
- viewModel.previewAction.value!!.invoke()
- viewModel.actions.value[1].onClicked!!.invoke()
+ val previewActionCaptor = argumentCaptor<() -> Unit>()
+ verify(actionsCallback).providePreviewAction(previewActionCaptor.capture())
+ val actionButtonCaptor = argumentCaptor<() -> Unit>()
+ verify(actionsCallback, times(2))
+ .provideActionButton(any(), any(), actionButtonCaptor.capture())
+
+ actionButtonCaptor.firstValue.invoke()
+ previewActionCaptor.firstValue.invoke()
+ actionButtonCaptor.secondValue.invoke()
actionsProvider.setCompletedScreenshot(validResult)
- verify(uiEventLogger).log(eq(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED), eq(0), eq(""))
+ verify(uiEventLogger).log(eq(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED), eq(0), eq(""))
val intentCaptor = argumentCaptor<Intent>()
verify(actionExecutor)
- .startSharedTransition(capture(intentCaptor), eq(Process.myUserHandle()), eq(false))
- assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_CHOOSER)
+ .startSharedTransition(intentCaptor.capture(), eq(Process.myUserHandle()), eq(true))
+ assertThat(intentCaptor.firstValue.action).isEqualTo(Intent.ACTION_EDIT)
}
@Test
@@ -117,9 +125,12 @@
actionsProvider = createActionsProvider()
val onScrollClick = mock<Runnable>()
- val numActions = viewModel.actions.value.size
actionsProvider.onScrollChipReady(onScrollClick)
- viewModel.actions.value[numActions].onClicked!!.invoke()
+ val actionButtonCaptor = argumentCaptor<() -> Unit>()
+ // share, edit, scroll
+ verify(actionsCallback, times(3))
+ .provideActionButton(any(), any(), actionButtonCaptor.capture())
+ actionButtonCaptor.thirdValue.invoke()
verify(onScrollClick).run()
}
@@ -129,10 +140,13 @@
actionsProvider = createActionsProvider()
val onScrollClick = mock<Runnable>()
- val numActions = viewModel.actions.value.size
actionsProvider.onScrollChipReady(onScrollClick)
+ val actionButtonCaptor = argumentCaptor<() -> Unit>()
actionsProvider.onScrollChipInvalidated()
- viewModel.actions.value[numActions].onClicked!!.invoke()
+ // share, edit, scroll
+ verify(actionsCallback, times(3))
+ .provideActionButton(any(), any(), actionButtonCaptor.capture())
+ actionButtonCaptor.thirdValue.invoke()
verify(onScrollClick, never()).run()
}
@@ -143,11 +157,15 @@
val onScrollClick = mock<Runnable>()
val onScrollClick2 = mock<Runnable>()
- val numActions = viewModel.actions.value.size
+
actionsProvider.onScrollChipReady(onScrollClick)
actionsProvider.onScrollChipInvalidated()
actionsProvider.onScrollChipReady(onScrollClick2)
- viewModel.actions.value[numActions].onClicked!!.invoke()
+ val actionButtonCaptor = argumentCaptor<() -> Unit>()
+ // share, edit, scroll
+ verify(actionsCallback, times(3))
+ .provideActionButton(any(), any(), actionButtonCaptor.capture())
+ actionButtonCaptor.thirdValue.invoke()
verify(onScrollClick2).run()
verify(onScrollClick, never()).run()
@@ -156,11 +174,11 @@
private fun createActionsProvider(): ScreenshotActionsProvider {
return DefaultScreenshotActionsProvider(
context,
- viewModel,
uiEventLogger,
+ UUID.randomUUID(),
request,
- "testid",
- actionExecutor
+ actionExecutor,
+ actionsCallback,
)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
new file mode 100644
index 0000000..2a3c31a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
@@ -0,0 +1,100 @@
+/*
+ * 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
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
+import java.util.UUID
+import kotlin.test.Test
+import org.junit.Before
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ScreenshotActionsControllerTest : SysuiTestCase() {
+ private val screenshotData = mock<ScreenshotData>()
+ private val actionExecutor = mock<ActionExecutor>()
+ private val viewModel = mock<ScreenshotViewModel>()
+ private val onClick = mock<() -> Unit>()
+
+ private lateinit var actionsController: ScreenshotActionsController
+ private lateinit var fakeActionsProvider1: FakeActionsProvider
+ private lateinit var fakeActionsProvider2: FakeActionsProvider
+ private val actionsProviderFactory =
+ object : ScreenshotActionsProvider.Factory {
+ var isFirstCall = true
+ override fun create(
+ requestId: UUID,
+ request: ScreenshotData,
+ actionExecutor: ActionExecutor,
+ actionsCallback: ScreenshotActionsController.ActionsCallback
+ ): ScreenshotActionsProvider {
+ return if (isFirstCall) {
+ isFirstCall = false
+ fakeActionsProvider1 = FakeActionsProvider(actionsCallback)
+ fakeActionsProvider1
+ } else {
+ fakeActionsProvider2 = FakeActionsProvider(actionsCallback)
+ fakeActionsProvider2
+ }
+ }
+ }
+
+ @Before
+ fun setUp() {
+ actionsController =
+ ScreenshotActionsController(viewModel, actionsProviderFactory, actionExecutor)
+ }
+
+ @Test
+ fun setPreview_onCurrentScreenshot_updatesViewModel() {
+ actionsController.setCurrentScreenshot(screenshotData)
+ fakeActionsProvider1.callPreview(onClick)
+
+ verify(viewModel).setPreviewAction(onClick)
+ }
+
+ @Test
+ fun setPreview_onNonCurrentScreenshot_doesNotUpdateViewModel() {
+ actionsController.setCurrentScreenshot(screenshotData)
+ actionsController.setCurrentScreenshot(screenshotData)
+ fakeActionsProvider1.callPreview(onClick)
+
+ verify(viewModel, never()).setPreviewAction(any())
+ }
+
+ class FakeActionsProvider(
+ private val actionsCallback: ScreenshotActionsController.ActionsCallback
+ ) : ScreenshotActionsProvider {
+
+ fun callPreview(onClick: () -> Unit) {
+ actionsCallback.providePreviewAction(onClick)
+ }
+
+ override fun onScrollChipReady(onClick: Runnable) {}
+
+ override fun onScrollChipInvalidated() {}
+
+ override fun setCompletedScreenshot(result: ScreenshotSavedResult) {}
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index 49a467e..bde1445 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -35,8 +35,8 @@
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
-import com.android.systemui.communal.data.repository.FakeCommunalRepository
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -92,14 +92,14 @@
private lateinit var containerView: View
private lateinit var testableLooper: TestableLooper
- private lateinit var communalRepository: FakeCommunalRepository
+ private lateinit var communalRepository: FakeCommunalSceneRepository
private lateinit var underTest: GlanceableHubContainerController
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- communalRepository = kosmos.fakeCommunalRepository
+ communalRepository = kosmos.fakeCommunalSceneRepository
ambientTouchComponentFactory =
object : AmbientTouchComponent.Factory {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
index 0906d8e..9f752a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
@@ -22,7 +22,7 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.AnimatorTestRule
-import com.android.systemui.communal.data.repository.communalRepository
+import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.dump.DumpManager
@@ -181,7 +181,7 @@
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Idle(CommunalScenes.Communal)
)
- kosmos.communalRepository.setTransitionState(transitionState)
+ kosmos.communalSceneRepository.setTransitionState(transitionState)
runCurrent()
setDozeAmount(0f)
verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f)
@@ -195,7 +195,7 @@
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Idle(CommunalScenes.Communal)
)
- kosmos.communalRepository.setTransitionState(transitionState)
+ kosmos.communalSceneRepository.setTransitionState(transitionState)
runCurrent()
setDozeAmount(0f)
verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
index 6300953..cdc4733 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
@@ -60,7 +60,8 @@
telephonyManager,
testDispatcher,
testScope.backgroundScope,
- FakeLogBuffer.Factory.create(),
+ logBuffer = FakeLogBuffer.Factory.create(),
+ verboseLogBuffer = FakeLogBuffer.Factory.create(),
systemClock,
)
private val demoDataSource =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
index 6651676..02f53b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
@@ -94,7 +94,8 @@
telephonyManager,
dispatcher,
testScope.backgroundScope,
- FakeLogBuffer.Factory.create(),
+ logBuffer = FakeLogBuffer.Factory.create(),
+ verboseLogBuffer = FakeLogBuffer.Factory.create(),
systemClock,
)
@@ -451,7 +452,8 @@
telephonyManager,
dispatcher,
testScope.backgroundScope,
- FakeLogBuffer.Factory.create(),
+ logBuffer = FakeLogBuffer.Factory.create(),
+ verboseLogBuffer = FakeLogBuffer.Factory.create(),
systemClock,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryKosmos.kt
similarity index 77%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryKosmos.kt
index 482d60c..a7a18a0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryKosmos.kt
@@ -20,8 +20,9 @@
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
+val Kosmos.fakeCommunalSceneRepository by Fixture {
+ FakeCommunalSceneRepository(applicationScope = applicationCoroutineScope)
}
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.communalSceneRepository by
+ Fixture<CommunalSceneRepository> { fakeCommunalSceneRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
similarity index 88%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
index d958bae..a7bf87d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
@@ -14,14 +14,17 @@
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
-/** Fake implementation of [CommunalRepository]. */
+/** Fake implementation of [CommunalSceneRepository]. */
@OptIn(ExperimentalCoroutinesApi::class)
-class FakeCommunalRepository(
+class FakeCommunalSceneRepository(
applicationScope: CoroutineScope,
override val currentScene: MutableStateFlow<SceneKey> =
MutableStateFlow(CommunalScenes.Default),
-) : CommunalRepository {
- override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) {
+) : CommunalSceneRepository {
+ override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) =
+ snapToScene(toScene)
+
+ override fun snapToScene(toScene: SceneKey) {
this.currentScene.value = toScene
this._transitionState.value = flowOf(ObservableTransitionState.Idle(toScene))
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index 3fe6973..1583d1c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -20,7 +20,6 @@
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.communal.data.repository.communalMediaRepository
import com.android.systemui.communal.data.repository.communalPrefsRepository
-import com.android.systemui.communal.data.repository.communalRepository
import com.android.systemui.communal.data.repository.communalWidgetRepository
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
import com.android.systemui.flags.Flags
@@ -45,7 +44,7 @@
applicationScope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
broadcastDispatcher = broadcastDispatcher,
- communalRepository = communalRepository,
+ communalSceneInteractor = communalSceneInteractor,
widgetRepository = communalWidgetRepository,
communalPrefsRepository = communalPrefsRepository,
mediaRepository = communalMediaRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorKosmos.kt
similarity index 64%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorKosmos.kt
index 482d60c..ee48c10 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorKosmos.kt
@@ -14,14 +14,16 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.communal.domain.interactor
+import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.communalSceneInteractor: CommunalSceneInteractor by
+ Kosmos.Fixture {
+ CommunalSceneInteractor(
+ applicationScope = applicationCoroutineScope,
+ communalSceneRepository = communalSceneRepository,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 96a4049..1a45c42 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -125,6 +125,9 @@
private val _isEncryptedOrLockdown = MutableStateFlow(true)
override val isEncryptedOrLockdown: Flow<Boolean> = _isEncryptedOrLockdown
+ private val _isKeyguardEnabled = MutableStateFlow(true)
+ override val isKeyguardEnabled: StateFlow<Boolean> = _isKeyguardEnabled.asStateFlow()
+
override val topClippingBounds = MutableStateFlow<Int?>(null)
override fun setQuickSettingsVisible(isVisible: Boolean) {
@@ -184,6 +187,10 @@
_clockShouldBeCentered.value = shouldBeCentered
}
+ override fun setKeyguardEnabled(enabled: Boolean) {
+ _isKeyguardEnabled.value = enabled
+ }
+
fun dozeTimeTick(millis: Long) {
_dozeTimeTick.value = millis
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
index bbe37c1..42af25e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -34,5 +35,6 @@
keyguardInteractor = keyguardInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
+ deviceEntryRepository = deviceEntryRepository,
)
}
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 23dcd96..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
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -36,5 +37,6 @@
communalInteractor = communalInteractor,
powerInteractor = powerInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
+ deviceEntryRepository = deviceEntryRepository,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
index 604d9e4..4039ee6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
@@ -19,6 +19,7 @@
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
@@ -38,5 +39,7 @@
communalInteractor = communalInteractor,
keyguardOcclusionInteractor = keyguardOcclusionInteractor,
biometricSettingsRepository = biometricSettingsRepository,
+ keyguardRepository = keyguardRepository,
+ keyguardEnabledInteractor = keyguardEnabledInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
similarity index 60%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
index 482d60c..0667a6b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
@@ -14,14 +14,19 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.keyguardEnabledInteractor by
+ Kosmos.Fixture {
+ KeyguardEnabledInteractor(
+ applicationCoroutineScope,
+ keyguardRepository,
+ biometricSettingsRepository,
+ keyguardTransitionInteractor,
+ )
+ }
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 f2f4332..b862078 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
@@ -27,7 +27,7 @@
import com.android.systemui.classifier.falsingCollector
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
-import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -86,7 +86,7 @@
val configurationRepository by lazy { kosmos.fakeConfigurationRepository }
val configurationInteractor by lazy { kosmos.configurationInteractor }
val bouncerRepository by lazy { kosmos.bouncerRepository }
- val communalRepository by lazy { kosmos.fakeCommunalRepository }
+ val communalRepository by lazy { kosmos.fakeCommunalSceneRepository }
val headsUpNotificationInteractor by lazy { kosmos.headsUpNotificationInteractor }
val keyguardRepository by lazy { kosmos.fakeKeyguardRepository }
val keyguardBouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt
index d344b75..5b1f95a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/taskswitcher/TaskSwitcherKosmos.kt
@@ -20,8 +20,8 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.mediaprojection.data.repository.MediaProjectionManagerRepository
import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository
-import com.android.systemui.mediaprojection.taskswitcher.data.repository.MediaProjectionManagerRepository
import com.android.systemui.mediaprojection.taskswitcher.domain.interactor.TaskSwitchInteractor
import com.android.systemui.mediaprojection.taskswitcher.ui.viewmodel.TaskSwitcherNotificationViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconLabelVisibilityRepositoryKosmos.kt
similarity index 63%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconLabelVisibilityRepositoryKosmos.kt
index 482d60c..277dbb7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/IconLabelVisibilityRepositoryKosmos.kt
@@ -14,14 +14,8 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.qs.panels.data.repository
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.applicationCoroutineScope
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.iconLabelVisibilityRepository by Kosmos.Fixture { IconLabelVisibilityRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorKosmos.kt
similarity index 62%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorKosmos.kt
index 482d60c..7b9e4a1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorKosmos.kt
@@ -14,14 +14,18 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.qs.panels.domain.interactor
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.log.core.FakeLogBuffer
+import com.android.systemui.qs.panels.data.repository.iconLabelVisibilityRepository
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.iconLabelVisibilityInteractor by
+ Kosmos.Fixture {
+ IconLabelVisibilityInteractor(
+ iconLabelVisibilityRepository,
+ FakeLogBuffer.Factory.create(),
+ applicationCoroutineScope
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
index 34b266a..82cfaf5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
@@ -18,6 +18,8 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.ui.compose.InfiniteGridLayout
+import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.infiniteGridSizeViewModel
val Kosmos.infiniteGridLayout by
- Kosmos.Fixture { InfiniteGridLayout(iconTilesInteractor, infiniteGridSizeInteractor) }
+ Kosmos.Fixture { InfiniteGridLayout(iconTilesViewModel, infiniteGridSizeViewModel) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/PartitionedGridLayoutKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/PartitionedGridLayoutKosmos.kt
index 4febfe91..37c9552 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/PartitionedGridLayoutKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/PartitionedGridLayoutKosmos.kt
@@ -18,6 +18,7 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.ui.compose.PartitionedGridLayout
+import com.android.systemui.qs.panels.ui.viewmodel.partitionedGridViewModel
val Kosmos.partitionedGridLayout by
- Kosmos.Fixture { PartitionedGridLayout(iconTilesInteractor, infiniteGridSizeInteractor) }
+ Kosmos.Fixture { PartitionedGridLayout(partitionedGridViewModel) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
similarity index 63%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
index 482d60c..daf6087 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconLabelVisibilityViewModelKosmos.kt
@@ -14,14 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.qs.panels.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.qs.panels.domain.interactor.iconLabelVisibilityInteractor
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.iconLabelVisibilityViewModel by
+ Kosmos.Fixture { IconLabelVisibilityViewModelImpl(iconLabelVisibilityInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModelKosmos.kt
similarity index 63%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModelKosmos.kt
index 482d60c..89b42a6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/IconTilesViewModelKosmos.kt
@@ -14,14 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.qs.panels.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.qs.panels.domain.interactor.iconTilesInteractor
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.iconTilesViewModel by Kosmos.Fixture { IconTilesViewModelImpl(iconTilesInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModelKosmos.kt
similarity index 63%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModelKosmos.kt
index 482d60c..f6dfb8b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModelKosmos.kt
@@ -14,14 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.qs.panels.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.qs.panels.domain.interactor.infiniteGridSizeInteractor
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.infiniteGridSizeViewModel by
+ Kosmos.Fixture { InfiniteGridSizeViewModelImpl(infiniteGridSizeInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModelKosmos.kt
similarity index 63%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModelKosmos.kt
index 482d60c..b07cc7d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/CommunalRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModelKosmos.kt
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui.communal.data.repository
+package com.android.systemui.qs.panels.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.applicationCoroutineScope
-val Kosmos.fakeCommunalRepository by Fixture {
- FakeCommunalRepository(applicationScope = applicationCoroutineScope)
-}
-
-val Kosmos.communalRepository by Fixture<CommunalRepository> { fakeCommunalRepository }
+val Kosmos.partitionedGridViewModel by
+ Kosmos.Fixture {
+ PartitionedGridViewModel(
+ iconTilesViewModel,
+ infiniteGridSizeViewModel,
+ iconLabelVisibilityViewModel,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt
index 4f5c9b4..5b6fd8c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt
@@ -45,6 +45,7 @@
other ?: return
}
check("icon").that(actual.icon()).isEqualTo(other.icon())
+ check("iconRes").that(actual.iconRes).isEqualTo(other.iconRes)
check("label").that(actual.label).isEqualTo(other.label)
check("activationState").that(actual.activationState).isEqualTo(other.activationState)
check("secondaryLabel").that(actual.secondaryLabel).isEqualTo(other.secondaryLabel)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
index e0f60e9..b6194e3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
@@ -19,8 +19,8 @@
import android.content.Context
import android.view.View
import com.android.systemui.settings.brightness.MirrorController
-import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterNotNull
@@ -41,7 +41,7 @@
override val customizerAnimationDuration = _animationDuration.asStateFlow()
private val _view = MutableStateFlow<View?>(null)
- override val qsView: Flow<View> = _view.filterNotNull()
+ override val qsView: StateFlow<View?> = _view.asStateFlow()
private val _state = MutableStateFlow<QSSceneAdapter.State?>(null)
val state = _state.filterNotNull()
@@ -64,6 +64,8 @@
}
}
+ override fun applyLatestExpansionAndSquishiness() {}
+
fun setCustomizing(value: Boolean) {
updateCustomizerFlows(if (value) CustomizerState.Showing else CustomizerState.Hidden)
}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index b414b25..2d99c96 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -270,7 +270,8 @@
PackageManagerInternal.class);
RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
mBackupManagerService.getPackageManager(), allowApks, info, signatures,
- pmi, mUserId, mBackupEligibilityRules);
+ pmi, mUserId, mBackupEligibilityRules,
+ mBackupManagerService.getContext());
mManifestSignatures.put(info.packageName, signatures);
mPackagePolicies.put(pkg, restorePolicy);
mPackageInstallers.put(pkg, info.installerPackageName);
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index 78a9952..4860a27 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -31,6 +31,7 @@
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_MISSING_SIGNATURE;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
@@ -53,17 +54,22 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
+import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Slog;
import com.android.server.backup.FileMetadata;
+import com.android.server.backup.Flags;
import com.android.server.backup.restore.RestorePolicy;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
/**
* Utility methods to read backup tar file.
@@ -390,7 +396,7 @@
boolean allowApks, FileMetadata info, Signature[] signatures,
PackageManagerInternal pmi, int userId, Context context) {
return chooseRestorePolicy(packageManager, allowApks, info, signatures, pmi, userId,
- BackupEligibilityRules.forBackup(packageManager, pmi, userId, context));
+ BackupEligibilityRules.forBackup(packageManager, pmi, userId, context), context);
}
/**
@@ -406,7 +412,8 @@
*/
public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
boolean allowApks, FileMetadata info, Signature[] signatures,
- PackageManagerInternal pmi, int userId, BackupEligibilityRules eligibilityRules) {
+ PackageManagerInternal pmi, int userId, BackupEligibilityRules eligibilityRules,
+ Context context) {
if (signatures == null) {
return RestorePolicy.IGNORE;
}
@@ -448,6 +455,16 @@
pkgInfo,
LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
null);
+ } else if (isAllowlistedForVToURestore(info, pkgInfo, userId, context)) {
+ Slog.i(TAG, "Performing a V to U downgrade; package: "
+ + info.packageName
+ + " is allowlisted");
+ policy = RestorePolicy.ACCEPT;
+ mBackupManagerMonitorEventSender.monitorEvent(
+ LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE,
+ pkgInfo,
+ LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+ null);
} else {
// The data is from a newer version of the app than
// is presently installed. That means we can only
@@ -751,6 +768,36 @@
return true;
}
+ // checks the sdk of the target/source device for a B&R operation.
+ // system components can opt in of V->U restore via allowlist.
+ @SuppressWarnings("AndroidFrameworkCompatChange")
+ private boolean isAllowlistedForVToURestore(FileMetadata backupFileInfo,
+ PackageInfo installedPackageInfo,
+ int userId, Context context) {
+ // We assume that the package version matches the sdk (e.g. version 35 means V).
+ // This is true for most of the system components ( and it is specifically true for those
+ // that are in the allowlist)
+ // In order to check if this is a V to U transfer we check if the package version from the
+ // backup is 35 and on the target is 34.
+ // We don't need to check the V to U denylist here since a package can only make it
+ // to TarBackupReader if allowed and not denied (from PerformUnifiedRestoreTask)
+
+ String vToUAllowlist = getVToUAllowlist(context, userId);
+ List<String> mVToUAllowlist = Arrays.asList(vToUAllowlist.split(","));
+ return Flags.enableVToURestoreForSystemComponentsInAllowlist()
+ && (installedPackageInfo.getLongVersionCode()
+ == Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ && (backupFileInfo.version > Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ && (mVToUAllowlist.contains(installedPackageInfo.packageName));
+ }
+
+ private String getVToUAllowlist(Context context, int userId) {
+ return Settings.Secure.getStringForUser(
+ context.getContentResolver(),
+ Settings.Secure.V_TO_U_RESTORE_ALLOWLIST,
+ userId);
+ }
+
private static long extractRadix(byte[] data, int offset, int maxChars, int radix)
throws IOException {
long value = 0;
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 211f952..db4840d 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -83,6 +83,8 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.ServiceThread;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
@@ -98,8 +100,6 @@
import java.util.Random;
import java.util.Set;
-import dalvik.annotation.optimization.NeverCompile;
-
public final class CachedAppOptimizer {
// Flags stored in the DeviceConfig API.
@@ -2633,7 +2633,7 @@
public void binderError(int debugPid, ProcessRecord app, int code, int flags, int err) {
Slog.w(TAG_AM, "pid " + debugPid + " " + (app == null ? "null" : app.processName)
+ " sent binder code " + code + " with flags " + flags
- + " to frozen apps and got error " + err);
+ + " and got error " + err);
// Do nothing if the binder error callback is not enabled.
// That means the frozen apps in a wrong state will be killed when they are unfrozen later.
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index fa8832c..219de70 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -36,6 +36,7 @@
import static android.os.Process.startWebView;
import static android.system.OsConstants.EAGAIN;
+import static com.android.sdksandbox.flags.Flags.selinuxInputSelector;
import static com.android.sdksandbox.flags.Flags.selinuxSdkSandboxAudit;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
@@ -2066,11 +2067,16 @@
}
}
- return app.info.seInfo
- + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser) + extraInfo;
+ // The order of selectors in seInfo matters, the string is terminated by the word complete.
+ if (selinuxInputSelector()) {
+ return app.info.seInfo + extraInfo + TextUtils.emptyIfNull(app.info.seInfoUser);
+ } else {
+ return app.info.seInfo
+ + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser)
+ + extraInfo;
+ }
}
-
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index c9612ca..e0790da 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -293,6 +293,7 @@
Iterator<Entry<Pair<Integer, String>, AdiDeviceState>> iterator =
mDeviceInventory.entrySet().iterator();
if (iterator.hasNext()) {
+ iterator.next();
iterator.remove();
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 7deef2f..72c5254 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -2123,7 +2123,10 @@
return AudioProductStrategy.getAudioProductStrategies();
}
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ @android.annotation.EnforcePermission(anyOf = {
+ MODIFY_AUDIO_SETTINGS_PRIVILEGED,
+ android.Manifest.permission.MODIFY_AUDIO_ROUTING
+ })
/**
* @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
* platform configuration file.
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 30d12e6..1949e6f 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -56,10 +56,12 @@
import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.clamper.BrightnessClamperController;
import com.android.server.display.config.HysteresisLevels;
+import com.android.server.display.feature.DisplayManagerFlags;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.TimeUnit;
/**
* Manages the associated display brightness when in auto-brightness mode. This is also
@@ -206,7 +208,7 @@
private float mScreenBrighteningThreshold;
private float mScreenDarkeningThreshold;
// The most recent light sample.
- private float mLastObservedLux = INVALID_LUX;
+ private float mLastObservedLux;
// The time of the most light recent sample.
private long mLastObservedLuxTime;
@@ -277,6 +279,8 @@
private Clock mClock;
private final Injector mInjector;
+ private final DisplayManagerFlags mDisplayManagerFlags;
+
AutomaticBrightnessController(Callbacks callbacks, Looper looper,
SensorManager sensorManager, Sensor lightSensor,
SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap,
@@ -291,7 +295,8 @@
BrightnessRangeController brightnessModeController,
BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userNits,
- BrightnessClamperController brightnessClamperController) {
+ BrightnessClamperController brightnessClamperController,
+ DisplayManagerFlags displayManagerFlags) {
this(new Injector(), callbacks, looper, sensorManager, lightSensor,
brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin, brightnessMax,
dozeScaleFactor, lightSensorRate, initialLightSensorRate,
@@ -301,7 +306,7 @@
screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
screenBrightnessThresholdsIdle, context, brightnessModeController,
brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux,
- userNits, brightnessClamperController
+ userNits, brightnessClamperController, displayManagerFlags
);
}
@@ -320,9 +325,10 @@
BrightnessRangeController brightnessRangeController,
BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userNits,
- BrightnessClamperController brightnessClamperController) {
+ BrightnessClamperController brightnessClamperController,
+ DisplayManagerFlags displayManagerFlags) {
mInjector = injector;
- mClock = injector.createClock();
+ mClock = injector.createClock(displayManagerFlags.offloadControlsDozeAutoBrightness());
mContext = context;
mCallbacks = callbacks;
mSensorManager = sensorManager;
@@ -367,6 +373,7 @@
mBrightnessClamperController = brightnessClamperController;
mBrightnessThrottler = brightnessThrottler;
mBrightnessMappingStrategyMap = brightnessMappingStrategyMap;
+ mDisplayManagerFlags = displayManagerFlags;
// Use the given short-term model
if (userNits != BrightnessMappingStrategy.INVALID_NITS) {
@@ -429,34 +436,6 @@
return mRawScreenAutoBrightness;
}
- /**
- * Get the automatic screen brightness based on the last observed lux reading. Used e.g. when
- * entering doze - we disable the light sensor, invalidate the lux, but we still need to set
- * the initial brightness in doze mode.
- */
- public float getAutomaticScreenBrightnessBasedOnLastUsedLux(
- BrightnessEvent brightnessEvent) {
- float lastUsedLux = mAmbientLux;
- if (lastUsedLux == INVALID_LUX) {
- return PowerManager.BRIGHTNESS_INVALID_FLOAT;
- }
-
- float brightness = mCurrentBrightnessMapper.getBrightness(lastUsedLux,
- mForegroundAppPackageName, mForegroundAppCategory);
- if (shouldApplyDozeScaleFactor()) {
- brightness *= mDozeScaleFactor;
- }
-
- if (brightnessEvent != null) {
- brightnessEvent.setLux(lastUsedLux);
- brightnessEvent.setRecommendedBrightness(brightness);
- brightnessEvent.setFlags(brightnessEvent.getFlags()
- | (shouldApplyDozeScaleFactor() ? BrightnessEvent.FLAG_DOZE_SCALE : 0));
- brightnessEvent.setAutoBrightnessMode(getMode());
- }
- return brightness;
- }
-
public boolean hasValidAmbientLux() {
return mAmbientLuxValid;
}
@@ -747,7 +726,6 @@
mRecentLightSamples++;
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
mAmbientLightRingBuffer.push(time, lux);
-
// Remember this sample value.
mLastObservedLux = lux;
mLastObservedLuxTime = time;
@@ -891,7 +869,7 @@
}
private void updateAmbientLux() {
- long time = mClock.uptimeMillis();
+ long time = mClock.getSensorEventScaleTime();
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
updateAmbientLux(time);
}
@@ -968,7 +946,16 @@
Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for " +
nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime));
}
- mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime);
+
+ // The nextTransitionTime is computed as elapsedTime(Which also accounts for the time when
+ // android was sleeping) as the main reference. However, handlers work on the uptime(Not
+ // accounting for the time when android was sleeping)
+ mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX,
+ convertToUptime(nextTransitionTime));
+ }
+
+ private long convertToUptime(long time) {
+ return time - mClock.getSensorEventScaleTime() + mClock.uptimeMillis();
}
private void updateAutoBrightness(boolean sendUpdate, boolean isManuallySet) {
@@ -1185,15 +1172,13 @@
}
mPausedShortTermModel.copyFrom(tempShortTermModel);
}
-
- update();
}
/**
* Responsible for switching the AutomaticBrightnessMode of the associated display. Also takes
* care of resetting the short term model wherever required
*/
- public void switchMode(@AutomaticBrightnessMode int mode) {
+ public void switchMode(@AutomaticBrightnessMode int mode, boolean sendUpdate) {
if (!mBrightnessMappingStrategyMap.contains(mode)) {
return;
}
@@ -1208,6 +1193,11 @@
resetShortTermModel();
mCurrentBrightnessMapper = mBrightnessMappingStrategyMap.get(mode);
}
+ if (sendUpdate) {
+ update();
+ } else {
+ updateAutoBrightness(/* sendUpdate= */ false, /* isManuallySet= */ false);
+ }
}
float getUserLux() {
@@ -1391,7 +1381,9 @@
@Override
public void onSensorChanged(SensorEvent event) {
if (mLightSensorEnabled) {
- final long time = mClock.uptimeMillis();
+ // The time received from the sensor is in nano seconds, hence changing it to ms
+ final long time = (mDisplayManagerFlags.offloadControlsDozeAutoBrightness())
+ ? TimeUnit.NANOSECONDS.toMillis(event.timestamp) : mClock.uptimeMillis();
final float lux = event.values[0];
handleLightSensorEvent(time, lux);
}
@@ -1424,6 +1416,12 @@
* Returns current time in milliseconds since boot, not counting time spent in deep sleep.
*/
long uptimeMillis();
+
+ /**
+ * Gets the time on either the elapsedTime or the uptime scale, depending on how we
+ * processing the events from the sensor
+ */
+ long getSensorEventScaleTime();
}
/**
@@ -1571,7 +1569,8 @@
StringBuilder buf = new StringBuilder();
buf.append('[');
for (int i = 0; i < mCount; i++) {
- final long next = i + 1 < mCount ? getTime(i + 1) : mClock.uptimeMillis();
+ final long next = i + 1 < mCount ? getTime(i + 1)
+ : mClock.getSensorEventScaleTime();
if (i != 0) {
buf.append(", ");
}
@@ -1596,13 +1595,31 @@
}
}
+ private static class RealClock implements Clock {
+ private final boolean mOffloadControlsDozeBrightness;
+
+ RealClock(boolean offloadControlsDozeBrightness) {
+ mOffloadControlsDozeBrightness = offloadControlsDozeBrightness;
+ }
+
+ @Override
+ public long uptimeMillis() {
+ return SystemClock.uptimeMillis();
+ }
+
+ public long getSensorEventScaleTime() {
+ return (mOffloadControlsDozeBrightness)
+ ? SystemClock.elapsedRealtime() : uptimeMillis();
+ }
+ }
+
public static class Injector {
public Handler getBackgroundThreadHandler() {
return BackgroundThread.getHandler();
}
- Clock createClock() {
- return SystemClock::uptimeMillis;
+ Clock createClock(boolean offloadControlsDozeBrightness) {
+ return new RealClock(offloadControlsDozeBrightness);
}
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 27ea1cd..d4c0b01 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1745,6 +1745,7 @@
if (projection != null) {
IBinder taskWindowContainerToken = projection.getLaunchCookie() == null ? null
: projection.getLaunchCookie().binder;
+ int taskId = projection.getTaskId();
if (taskWindowContainerToken == null) {
// Record a particular display.
session = ContentRecordingSession.createDisplaySession(
@@ -1752,7 +1753,7 @@
} else {
// Record a single task indicated by the launch cookie.
session = ContentRecordingSession.createTaskSession(
- taskWindowContainerToken);
+ taskWindowContainerToken, taskId);
}
}
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java b/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
index 65c9f35..f77a360 100644
--- a/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
+++ b/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
@@ -52,6 +52,14 @@
}
@Override
+ public boolean allowAutoBrightnessInDoze() {
+ if (mDisplayOffloader == null) {
+ return false;
+ }
+ return mDisplayOffloader.allowAutoBrightnessInDoze();
+ }
+
+ @Override
public void updateBrightness(float brightness) {
if (mIsActive) {
mDisplayPowerController.setBrightnessFromOffload(brightness);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 0fcdf19..7d482f7 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1115,7 +1115,7 @@
screenBrightnessThresholdsIdle, mContext, mBrightnessRangeController,
mBrightnessThrottler, mDisplayDeviceConfig.getAmbientHorizonShort(),
mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userNits,
- mBrightnessClamperController);
+ mBrightnessClamperController, mFlags);
mDisplayBrightnessController.setUpAutoBrightness(
mAutomaticBrightnessController, mSensorManager, mDisplayDeviceConfig, mHandler,
defaultModeBrightnessMapper, mIsEnabled, mLeadDisplayId);
@@ -1185,7 +1185,8 @@
@AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
boolean isIdle = mode == AUTO_BRIGHTNESS_MODE_IDLE;
if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.switchMode(mode);
+ // Set sendUpdate to true to make sure that updatePowerState() gets called
+ mAutomaticBrightnessController.switchMode(mode, /* sendUpdate= */ true);
setAnimatorRampSpeeds(isIdle);
}
Message msg = mHandler.obtainMessage();
@@ -1334,7 +1335,6 @@
mDisplayStateController.shouldPerformScreenOffTransition());
state = mPowerState.getScreenState();
-
DisplayBrightnessState displayBrightnessState = mDisplayBrightnessController
.updateBrightness(mPowerRequest, state);
float brightnessState = displayBrightnessState.getBrightness();
@@ -1366,17 +1366,26 @@
// request changes.
final boolean wasShortTermModelActive =
mAutomaticBrightnessStrategy.isShortTermModelActive();
+ boolean allowAutoBrightnessWhileDozing =
+ mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig();
+ if (mFlags.offloadControlsDozeAutoBrightness() && mFlags.isDisplayOffloadEnabled()
+ && mDisplayOffloadSession != null) {
+ allowAutoBrightnessWhileDozing &= mDisplayOffloadSession.allowAutoBrightnessInDoze();
+ }
if (!mFlags.isRefactorDisplayPowerControllerEnabled()) {
// Switch to doze auto-brightness mode if needed
if (mFlags.areAutoBrightnessModesEnabled() && mAutomaticBrightnessController != null
&& !mAutomaticBrightnessController.isInIdleMode()) {
+ // Set sendUpdate to false, we're already in updatePowerState() so there's no need
+ // to trigger it again
mAutomaticBrightnessController.switchMode(Display.isDozeState(state)
- ? AUTO_BRIGHTNESS_MODE_DOZE : AUTO_BRIGHTNESS_MODE_DEFAULT);
+ ? AUTO_BRIGHTNESS_MODE_DOZE : AUTO_BRIGHTNESS_MODE_DEFAULT,
+ /* sendUpdate= */ false);
}
mAutomaticBrightnessStrategy.setAutoBrightnessState(state,
- mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig(),
- mBrightnessReasonTemp.getReason(), mPowerRequest.policy,
+ allowAutoBrightnessWhileDozing, mBrightnessReasonTemp.getReason(),
+ mPowerRequest.policy,
mDisplayBrightnessController.getLastUserSetScreenBrightness(),
userSetBrightnessChanged);
}
@@ -1443,47 +1452,27 @@
}
if (Display.isDozeState(state)) {
- // If there's an offload session, we need to set the initial doze brightness before
- // the offload session starts controlling the brightness.
- // During the transition DOZE_SUSPEND -> DOZE -> DOZE_SUSPEND, this brightness strategy
- // will be selected again, meaning that no new brightness will be sent to the hardware
- // and the display will stay at the brightness level set by the offload session.
+ // TODO(b/329676661): Introduce a config property to choose between this brightness
+ // strategy and DOZE_DEFAULT
+ // On some devices, when auto-brightness is disabled and the device is dozing, we use
+ // the current brightness setting scaled by the doze scale factor
if ((Float.isNaN(brightnessState)
|| displayBrightnessState.getDisplayBrightnessStrategyName()
.equals(DisplayBrightnessStrategyConstants.FALLBACK_BRIGHTNESS_STRATEGY_NAME))
&& mFlags.isDisplayOffloadEnabled()
- && mDisplayOffloadSession != null) {
- if (mAutomaticBrightnessController != null
- && mAutomaticBrightnessStrategy.shouldUseAutoBrightness()) {
- // Use the auto-brightness curve and the last observed lux
- rawBrightnessState = mAutomaticBrightnessController
- .getAutomaticScreenBrightnessBasedOnLastUsedLux(
- mTempBrightnessEvent);
- } else {
- rawBrightnessState = getDozeBrightnessForOffload();
- mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
- | BrightnessEvent.FLAG_DOZE_SCALE);
- }
-
- if (BrightnessUtils.isValidBrightnessValue(rawBrightnessState)) {
- brightnessState = clampScreenBrightness(rawBrightnessState);
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_INITIAL);
-
- if (mAutomaticBrightnessController != null
- && mAutomaticBrightnessStrategy.shouldUseAutoBrightness()) {
- // Keep the brightness in the setting so that we can use it after the screen
- // turns on, until a lux sample becomes available. We don't do this when
- // auto-brightness is disabled - in that situation we still want to use
- // the last brightness from when the screen was on.
- updateScreenBrightnessSetting = currentBrightnessSetting != brightnessState;
- }
- }
+ && mDisplayOffloadSession != null
+ && (mAutomaticBrightnessController == null
+ || !mAutomaticBrightnessStrategy.shouldUseAutoBrightness())) {
+ rawBrightnessState = getDozeBrightnessForOffload();
+ brightnessState = clampScreenBrightness(rawBrightnessState);
+ mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_MANUAL);
+ mTempBrightnessEvent.setFlags(
+ mTempBrightnessEvent.getFlags() | BrightnessEvent.FLAG_DOZE_SCALE);
}
// Use default brightness when dozing unless overridden.
- if (Float.isNaN(brightnessState)
- || displayBrightnessState.getDisplayBrightnessStrategyName()
- .equals(DisplayBrightnessStrategyConstants.FALLBACK_BRIGHTNESS_STRATEGY_NAME)) {
+ if (Float.isNaN(brightnessState) && Display.isDozeState(state)
+ && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()) {
rawBrightnessState = mScreenBrightnessDozeConfig;
brightnessState = clampScreenBrightness(rawBrightnessState);
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
@@ -3169,7 +3158,8 @@
BrightnessRangeController brightnessModeController,
BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userNits,
- BrightnessClamperController brightnessClamperController) {
+ BrightnessClamperController brightnessClamperController,
+ DisplayManagerFlags displayManagerFlags) {
return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin,
@@ -3180,7 +3170,7 @@
screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
screenBrightnessThresholdsIdle, context, brightnessModeController,
brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux,
- userNits, brightnessClamperController);
+ userNits, brightnessClamperController, displayManagerFlags);
}
BrightnessMappingStrategy getDefaultModeBrightnessMapper(Context context,
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessReason.java b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
index fc95d15..9bf10a7 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessReason.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
@@ -40,8 +40,8 @@
public static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 9;
public static final int REASON_FOLLOWER = 10;
public static final int REASON_OFFLOAD = 11;
- public static final int REASON_DOZE_INITIAL = 12;
- public static final int REASON_MAX = REASON_DOZE_INITIAL;
+ public static final int REASON_DOZE_MANUAL = 12;
+ public static final int REASON_MAX = REASON_DOZE_MANUAL;
public static final int MODIFIER_DIMMED = 0x1;
public static final int MODIFIER_LOW_POWER = 0x2;
@@ -208,8 +208,8 @@
return "follower";
case REASON_OFFLOAD:
return "offload";
- case REASON_DOZE_INITIAL:
- return "doze_initial";
+ case REASON_DOZE_MANUAL:
+ return "doze_manual";
default:
return Integer.toString(reason);
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index 37b6931..2907364 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -15,8 +15,6 @@
*/
package com.android.server.display.brightness.strategy;
-import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
-
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
@@ -129,9 +127,11 @@
public void setAutoBrightnessState(int targetDisplayState,
boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy,
float lastUserSetScreenBrightness, boolean userSetBrightnessChanged) {
- switchMode(targetDisplayState);
+ // We are still in the process of updating the power state, so there's no need to trigger
+ // an update again
+ switchMode(targetDisplayState, /* sendUpdate= */ false);
final boolean autoBrightnessEnabledInDoze =
- allowAutoBrightnessWhileDozingConfig && policy == POLICY_DOZE;
+ allowAutoBrightnessWhileDozingConfig && Display.isDozeState(targetDisplayState);
mIsAutoBrightnessEnabled = shouldUseAutoBrightness()
&& (targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze)
&& brightnessReason != BrightnessReason.REASON_OVERRIDE
@@ -371,23 +371,6 @@
}
/**
- * Get the automatic screen brightness based on the last observed lux reading. Used e.g. when
- * entering doze - we disable the light sensor, invalidate the lux, but we still need to set
- * the initial brightness in doze mode.
- * @param brightnessEvent Event object to populate with details about why the specific
- * brightness was chosen.
- */
- public float getAutomaticScreenBrightnessBasedOnLastUsedLux(
- BrightnessEvent brightnessEvent) {
- float brightness = (mAutomaticBrightnessController != null)
- ? mAutomaticBrightnessController
- .getAutomaticScreenBrightnessBasedOnLastUsedLux(brightnessEvent)
- : PowerManager.BRIGHTNESS_INVALID_FLOAT;
- adjustAutomaticBrightnessStateIfValid(brightness);
- return brightness;
- }
-
- /**
* Returns if the auto brightness has been applied
*/
public boolean hasAppliedAutoBrightness() {
@@ -495,14 +478,12 @@
mIsShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints();
}
}
-
-
- private void switchMode(int state) {
+ private void switchMode(int state, boolean sendUpdate) {
if (mDisplayManagerFlags.areAutoBrightnessModesEnabled()
&& mAutomaticBrightnessController != null
&& !mAutomaticBrightnessController.isInIdleMode()) {
mAutomaticBrightnessController.switchMode(Display.isDozeState(state)
- ? AUTO_BRIGHTNESS_MODE_DOZE : AUTO_BRIGHTNESS_MODE_DEFAULT);
+ ? AUTO_BRIGHTNESS_MODE_DOZE : AUTO_BRIGHTNESS_MODE_DEFAULT, sendUpdate);
}
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
index 58670c9..4d9c18a 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
@@ -15,8 +15,6 @@
*/
package com.android.server.display.brightness.strategy;
-import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
-
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.display.BrightnessConfiguration;
@@ -110,7 +108,7 @@
boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy,
float lastUserSetScreenBrightness, boolean userSetBrightnessChanged) {
final boolean autoBrightnessEnabledInDoze =
- allowAutoBrightnessWhileDozingConfig && policy == POLICY_DOZE;
+ allowAutoBrightnessWhileDozingConfig && Display.isDozeState(targetDisplayState);
mIsAutoBrightnessEnabled = shouldUseAutoBrightness()
&& (targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze)
&& brightnessReason != BrightnessReason.REASON_OVERRIDE
@@ -273,23 +271,6 @@
}
/**
- * Get the automatic screen brightness based on the last observed lux reading. Used e.g. when
- * entering doze - we disable the light sensor, invalidate the lux, but we still need to set
- * the initial brightness in doze mode.
- * @param brightnessEvent Event object to populate with details about why the specific
- * brightness was chosen.
- */
- public float getAutomaticScreenBrightnessBasedOnLastUsedLux(
- BrightnessEvent brightnessEvent) {
- float brightness = (mAutomaticBrightnessController != null)
- ? mAutomaticBrightnessController
- .getAutomaticScreenBrightnessBasedOnLastUsedLux(brightnessEvent)
- : PowerManager.BRIGHTNESS_INVALID_FLOAT;
- adjustAutomaticBrightnessStateIfValid(brightness);
- return brightness;
- }
-
- /**
* Gets the auto-brightness adjustment flag change reason
*/
public int getAutoBrightnessAdjustmentReasonsFlags() {
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index a5414fc..8f775a5 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -154,6 +154,11 @@
Flags::useFusionProxSensor
);
+ private final FlagState mOffloadControlsDozeAutoBrightness = new FlagState(
+ Flags.FLAG_OFFLOAD_CONTROLS_DOZE_AUTO_BRIGHTNESS,
+ Flags::offloadControlsDozeAutoBrightness
+ );
+
private final FlagState mPeakRefreshRatePhysicalLimit = new FlagState(
Flags.FLAG_ENABLE_PEAK_REFRESH_RATE_PHYSICAL_LIMIT,
Flags::enablePeakRefreshRatePhysicalLimit
@@ -327,6 +332,13 @@
return mUseFusionProxSensor.getName();
}
+ /**
+ * @return Whether DisplayOffload should control auto-brightness in doze
+ */
+ public boolean offloadControlsDozeAutoBrightness() {
+ return mOffloadControlsDozeAutoBrightness.isEnabled();
+ }
+
public boolean isPeakRefreshRatePhysicalLimitEnabled() {
return mPeakRefreshRatePhysicalLimit.isEnabled();
}
@@ -373,6 +385,7 @@
pw.println(" " + mRefactorDisplayPowerController);
pw.println(" " + mResolutionBackupRestore);
pw.println(" " + mUseFusionProxSensor);
+ pw.println(" " + mOffloadControlsDozeAutoBrightness);
pw.println(" " + mPeakRefreshRatePhysicalLimit);
pw.println(" " + mIgnoreAppPreferredRefreshRate);
pw.println(" " + mSynthetic60hzModes);
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 316b6db..697218d 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -246,6 +246,17 @@
}
flag {
+ name: "offload_controls_doze_auto_brightness"
+ namespace: "display_manager"
+ description: "Allows the registered DisplayOffloader to control if auto-brightness is used in doze"
+ bug: "327392714"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_peak_refresh_rate_physical_limit"
namespace: "display_manager"
description: "Flag for adding physical refresh rate limit if smooth display setting is on "
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 4ee2e99..6da7a65 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
@@ -172,17 +172,22 @@
@Override
public String toString() {
- String out = ContextHubTransaction.typeToString(mTransactionType, true /* upperCase */)
- + " (";
+ StringBuilder out = new StringBuilder();
+ out.append(ContextHubTransaction.typeToString(mTransactionType,
+ /* upperCase= */ true));
+ out.append(" (");
if (mNanoAppId != null) {
- out += "appId = 0x" + Long.toHexString(mNanoAppId) + ", ";
+ out.append("appId = 0x");
+ out.append(Long.toHexString(mNanoAppId));
+ out.append(", ");
}
- out += "package = " + mPackage;
+ out.append("package = ");
+ out.append(mPackage);
if (mMessageSequenceNumber != null) {
- out += ", messageSequenceNumber = " + mMessageSequenceNumber;
+ out.append(", messageSequenceNumber = ");
+ out.append(mMessageSequenceNumber);
}
- out += ")";
-
- return out;
+ out.append(")");
+ return out.toString();
}
}
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index bbb19e3..e3d5c54 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -553,7 +553,8 @@
mProjectionGrant.getLaunchCookie() == null ? null
: mProjectionGrant.getLaunchCookie().binder;
setReviewedConsentSessionLocked(
- ContentRecordingSession.createTaskSession(taskWindowContainerToken));
+ ContentRecordingSession.createTaskSession(
+ taskWindowContainerToken, mProjectionGrant.mTaskId));
break;
}
}
@@ -977,6 +978,7 @@
private IBinder mToken;
private IBinder.DeathRecipient mDeathEater;
private boolean mRestoreSystemAlertWindow;
+ private int mTaskId = -1;
private LaunchCookie mLaunchCookie = null;
// Values for tracking token validity.
@@ -1197,12 +1199,26 @@
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override // Binder call
+ public void setTaskId(int taskId) {
+ setTaskId_enforcePermission();
+ mTaskId = taskId;
+ }
+
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
+ @Override // Binder call
public LaunchCookie getLaunchCookie() {
getLaunchCookie_enforcePermission();
return mLaunchCookie;
}
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
+ @Override // Binder call
+ public int getTaskId() {
+ getTaskId_enforcePermission();
+ return mTaskId;
+ }
+
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override
public boolean isValid() {
isValid_enforcePermission();
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 66e61c0..3cc0457 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -16,6 +16,9 @@
package com.android.server.notification;
+import static android.service.notification.Condition.STATE_TRUE;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER;
+
import android.app.INotificationManager;
import android.app.NotificationManager;
import android.content.ComponentName;
@@ -319,7 +322,20 @@
final Condition c = conditions[i];
final ConditionRecord r = getRecordLocked(c.id, info.component, true /*create*/);
r.info = info;
- r.condition = c;
+ if (android.app.Flags.modesUi()) {
+ // if user turned on the mode, ignore the update unless the app also wants the
+ // mode on. this will update the origin of the mode and let the owner turn it
+ // off when the context ends
+ if (r.condition != null && r.condition.source == UPDATE_ORIGIN_USER) {
+ if (r.condition.state == STATE_TRUE && c.state == STATE_TRUE) {
+ r.condition = c;
+ }
+ } else {
+ r.condition = c;
+ }
+ } else {
+ r.condition = c;
+ }
}
}
final int N = conditions.length;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6f65b79..c7b0f7d 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -7774,25 +7774,45 @@
}
private void checkRemoteViews(String pkg, String tag, int id, Notification notification) {
- if (removeRemoteView(pkg, tag, id, notification.contentView)) {
+ if (android.app.Flags.removeRemoteViews()) {
+ if (notification.contentView != null || notification.bigContentView != null
+ || notification.headsUpContentView != null
+ || (notification.publicVersion != null
+ && (notification.publicVersion.contentView != null
+ || notification.publicVersion.bigContentView != null
+ || notification.publicVersion.headsUpContentView != null))) {
+ Slog.i(TAG, "Removed customViews for " + pkg);
+ mUsageStats.registerImageRemoved(pkg);
+ }
notification.contentView = null;
- }
- if (removeRemoteView(pkg, tag, id, notification.bigContentView)) {
notification.bigContentView = null;
- }
- if (removeRemoteView(pkg, tag, id, notification.headsUpContentView)) {
notification.headsUpContentView = null;
- }
- if (notification.publicVersion != null) {
- if (removeRemoteView(pkg, tag, id, notification.publicVersion.contentView)) {
+ if (notification.publicVersion != null) {
notification.publicVersion.contentView = null;
- }
- if (removeRemoteView(pkg, tag, id, notification.publicVersion.bigContentView)) {
notification.publicVersion.bigContentView = null;
- }
- if (removeRemoteView(pkg, tag, id, notification.publicVersion.headsUpContentView)) {
notification.publicVersion.headsUpContentView = null;
}
+ } else {
+ if (removeRemoteView(pkg, tag, id, notification.contentView)) {
+ notification.contentView = null;
+ }
+ if (removeRemoteView(pkg, tag, id, notification.bigContentView)) {
+ notification.bigContentView = null;
+ }
+ if (removeRemoteView(pkg, tag, id, notification.headsUpContentView)) {
+ notification.headsUpContentView = null;
+ }
+ if (notification.publicVersion != null) {
+ if (removeRemoteView(pkg, tag, id, notification.publicVersion.contentView)) {
+ notification.publicVersion.contentView = null;
+ }
+ if (removeRemoteView(pkg, tag, id, notification.publicVersion.bigContentView)) {
+ notification.publicVersion.bigContentView = null;
+ }
+ if (removeRemoteView(pkg, tag, id, notification.publicVersion.headsUpContentView)) {
+ notification.publicVersion.headsUpContentView = null;
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index db18276..12e5180 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -341,10 +341,11 @@
static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0;
static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1;
- // must match: config_shortPressOnSettingsBehavior in config.xml
- static final int SHORT_PRESS_SETTINGS_NOTHING = 0;
- static final int SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL = 1;
- static final int LAST_SHORT_PRESS_SETTINGS_BEHAVIOR = SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL;
+ // must match: config_settingsKeyBehavior in config.xml
+ static final int SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY = 0;
+ static final int SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL = 1;
+ static final int SETTINGS_KEY_BEHAVIOR_NOTHING = 2;
+ static final int LAST_SETTINGS_KEY_BEHAVIOR = SETTINGS_KEY_BEHAVIOR_NOTHING;
static final int PENDING_KEY_NULL = -1;
@@ -370,8 +371,8 @@
static final int TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY = 1;
// Must match: config_searchKeyBehavior in config.xml
- static final int SEARCH_BEHAVIOR_DEFAULT_SEARCH = 0;
- static final int SEARCH_BEHAVIOR_TARGET_ACTIVITY = 1;
+ static final int SEARCH_KEY_BEHAVIOR_DEFAULT_SEARCH = 0;
+ static final int SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY = 1;
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -643,8 +644,8 @@
// What we do when the user double-taps on home
int mDoubleTapOnHomeBehavior;
- // What we do when the user presses on settings
- int mShortPressOnSettingsBehavior;
+ // What we do when the user presses the settings key
+ int mSettingsKeyBehavior;
// Must match config_primaryShortPressTargetActivity in config.xml
ComponentName mPrimaryShortPressTargetActivity;
@@ -2858,11 +2859,11 @@
mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE;
}
- mShortPressOnSettingsBehavior = res.getInteger(
- com.android.internal.R.integer.config_shortPressOnSettingsBehavior);
- if (mShortPressOnSettingsBehavior < SHORT_PRESS_SETTINGS_NOTHING
- || mShortPressOnSettingsBehavior > LAST_SHORT_PRESS_SETTINGS_BEHAVIOR) {
- mShortPressOnSettingsBehavior = SHORT_PRESS_SETTINGS_NOTHING;
+ mSettingsKeyBehavior = res.getInteger(
+ com.android.internal.R.integer.config_settingsKeyBehavior);
+ if (mSettingsKeyBehavior < SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY
+ || mSettingsKeyBehavior > LAST_SETTINGS_KEY_BEHAVIOR) {
+ mSettingsKeyBehavior = SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY;
}
}
@@ -3694,12 +3695,12 @@
case KeyEvent.KEYCODE_SEARCH:
if (firstDown && !keyguardOn) {
switch (mSearchKeyBehavior) {
- case SEARCH_BEHAVIOR_TARGET_ACTIVITY: {
+ case SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY: {
launchTargetSearchActivity();
logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_SEARCH);
return true;
}
- case SEARCH_BEHAVIOR_DEFAULT_SEARCH:
+ case SEARCH_KEY_BEHAVIOR_DEFAULT_SEARCH:
default:
break;
}
@@ -3778,14 +3779,16 @@
+ " interceptKeyBeforeQueueing");
return true;
case KeyEvent.KEYCODE_SETTINGS:
- if (mShortPressOnSettingsBehavior == SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL) {
- if (!down) {
+ if (firstDown) {
+ if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL) {
toggleNotificationPanel();
logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL);
+ } else if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY) {
+ showSystemSettings();
+ logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_SYSTEM_SETTINGS);
}
- return true;
}
- break;
+ return true;
case KeyEvent.KEYCODE_STEM_PRIMARY:
if (prepareToSendSystemKeyToApplication(focusedToken, event)) {
// Send to app.
@@ -6563,8 +6566,8 @@
pw.print("mLongPressOnPowerBehavior=");
pw.println(longPressOnPowerBehaviorToString(mLongPressOnPowerBehavior));
pw.print(prefix);
- pw.print("mShortPressOnSettingsBehavior=");
- pw.println(shortPressOnSettingsBehaviorToString(mShortPressOnSettingsBehavior));
+ pw.print("mSettingsKeyBehavior=");
+ pw.println(settingsKeyBehaviorToString(mSettingsKeyBehavior));
pw.print(prefix);
pw.print("mLongPressOnPowerAssistantTimeoutMs=");
pw.println(mLongPressOnPowerAssistantTimeoutMs);
@@ -6766,12 +6769,14 @@
}
}
- private static String shortPressOnSettingsBehaviorToString(int behavior) {
+ private static String settingsKeyBehaviorToString(int behavior) {
switch (behavior) {
- case SHORT_PRESS_SETTINGS_NOTHING:
- return "SHORT_PRESS_SETTINGS_NOTHING";
- case SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL:
- return "SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL";
+ case SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY:
+ return "SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY";
+ case SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL:
+ return "SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL";
+ case SETTINGS_KEY_BEHAVIOR_NOTHING:
+ return "SETTINGS_KEY_BEHAVIOR_NOTHING";
default:
return Integer.toString(behavior);
}
diff --git a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
index e1b4b88..fbdba4f 100644
--- a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
+++ b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
@@ -19,6 +19,7 @@
import android.annotation.CurrentTimeMillisLong;
import android.annotation.DurationMillisLong;
import android.annotation.NonNull;
+import android.os.BatteryStats;
import android.os.UserHandle;
import android.text.format.DateFormat;
import android.util.IndentingPrintWriter;
@@ -155,11 +156,17 @@
int powerComponentId = powerStats.descriptor.powerComponentId;
for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
if (stats.powerComponentId == powerComponentId) {
- stats.addPowerStats(powerStats, time);
+ stats.getConfig().getProcessor().addPowerStats(stats, powerStats, time);
}
}
}
+ public void noteStateChange(BatteryStats.HistoryItem item) {
+ for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
+ stats.getConfig().getProcessor().noteStateChange(stats, item);
+ }
+ }
+
void reset() {
mClockUpdates.clear();
mDurationMs = 0;
diff --git a/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java b/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java
index 884c26c..1ff7cb7 100644
--- a/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java
+++ b/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java
@@ -205,7 +205,7 @@
private static final PowerStatsProcessor NO_OP_PROCESSOR = new PowerStatsProcessor() {
@Override
- void finish(PowerComponentAggregatedPowerStats stats) {
+ void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
}
};
}
diff --git a/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsLayout.java b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsLayout.java
new file mode 100644
index 0000000..64c3446
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsLayout.java
@@ -0,0 +1,31 @@
+/*
+ * 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.power.stats;
+
+class BinaryStatePowerStatsLayout extends PowerStatsLayout {
+ BinaryStatePowerStatsLayout() {
+ addDeviceSectionUsageDuration();
+ // Add a section for consumed energy, even if the specific device does not
+ // have support EnergyConsumers. This is done to guarantee format compatibility between
+ // PowerStats created by a PowerStatsCollector and those produced by a PowerStatsProcessor.
+ addDeviceSectionEnergyConsumers(1);
+ addDeviceSectionPowerEstimate();
+
+ addUidSectionUsageDuration();
+ addUidSectionPowerEstimate();
+ }
+}
diff --git a/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsProcessor.java
new file mode 100644
index 0000000..490bd5e
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsProcessor.java
@@ -0,0 +1,276 @@
+/*
+ * 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.power.stats;
+
+import android.annotation.IntDef;
+import android.os.BatteryStats;
+import android.os.PersistableBundle;
+import android.os.Process;
+
+import com.android.internal.os.PowerStats;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+abstract class BinaryStatePowerStatsProcessor extends PowerStatsProcessor {
+ static final int STATE_OFF = 0;
+ static final int STATE_ON = 1;
+
+ @IntDef(flag = true, prefix = {"STATE_"}, value = {
+ STATE_OFF,
+ STATE_ON,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ protected @interface BinaryState {
+ }
+
+ private final int mPowerComponentId;
+ private final PowerStatsUidResolver mUidResolver;
+ private final UsageBasedPowerEstimator mUsageBasedPowerEstimator;
+ private boolean mEnergyConsumerSupported;
+ private int mInitiatingUid = Process.INVALID_UID;
+ private @BinaryState int mLastState = STATE_OFF;
+ private long mLastStateTimestamp;
+ private long mLastUpdateTimestamp;
+
+ private PowerStats.Descriptor mDescriptor;
+ private final BinaryStatePowerStatsLayout mStatsLayout = new BinaryStatePowerStatsLayout();
+ private PowerStats mPowerStats;
+ private PowerEstimationPlan mPlan;
+ private long[] mTmpDeviceStatsArray;
+ private long[] mTmpUidStatsArray;
+
+ BinaryStatePowerStatsProcessor(int powerComponentId,
+ PowerStatsUidResolver uidResolver, double averagePowerMilliAmp) {
+ mPowerComponentId = powerComponentId;
+ mUsageBasedPowerEstimator = new UsageBasedPowerEstimator(averagePowerMilliAmp);
+ mUidResolver = uidResolver;
+ }
+
+ protected abstract @BinaryState int getBinaryState(BatteryStats.HistoryItem item);
+
+ private void ensureInitialized() {
+ if (mDescriptor != null) {
+ return;
+ }
+
+ PersistableBundle extras = new PersistableBundle();
+ mStatsLayout.toExtras(extras);
+ mDescriptor = new PowerStats.Descriptor(mPowerComponentId,
+ mStatsLayout.getDeviceStatsArrayLength(), null, 0,
+ mStatsLayout.getUidStatsArrayLength(), extras);
+ mPowerStats = new PowerStats(mDescriptor);
+ mPowerStats.stats = new long[mDescriptor.statsArrayLength];
+ mTmpDeviceStatsArray = new long[mDescriptor.statsArrayLength];
+ mTmpUidStatsArray = new long[mDescriptor.uidStatsArrayLength];
+ }
+
+ @Override
+ void start(PowerComponentAggregatedPowerStats stats, long timestampMs) {
+ ensureInitialized();
+
+ // Establish a baseline at the beginning of an accumulation pass
+ mLastState = STATE_OFF;
+ mLastStateTimestamp = timestampMs;
+ mInitiatingUid = Process.INVALID_UID;
+ flushPowerStats(stats, mLastStateTimestamp);
+ }
+
+ @Override
+ void noteStateChange(PowerComponentAggregatedPowerStats stats,
+ BatteryStats.HistoryItem item) {
+ @BinaryState int state = getBinaryState(item);
+ if (state == mLastState) {
+ return;
+ }
+
+ if (state == STATE_ON) {
+ if (item.eventCode == (BatteryStats.HistoryItem.EVENT_STATE_CHANGE
+ | BatteryStats.HistoryItem.EVENT_FLAG_START)) {
+ mInitiatingUid = mUidResolver.mapUid(item.eventTag.uid);
+ }
+ } else {
+ recordUsageDuration(item.time);
+ mInitiatingUid = Process.INVALID_UID;
+ if (!mEnergyConsumerSupported) {
+ flushPowerStats(stats, item.time);
+ }
+ }
+ mLastStateTimestamp = item.time;
+ mLastState = state;
+ }
+
+ private void recordUsageDuration(long time) {
+ if (mLastState == STATE_OFF) {
+ return;
+ }
+
+ long durationMs = time - mLastStateTimestamp;
+ mStatsLayout.setUsageDuration(mPowerStats.stats,
+ mStatsLayout.getUsageDuration(mPowerStats.stats) + durationMs);
+
+ if (mInitiatingUid != Process.INVALID_UID) {
+ long[] uidStats = mPowerStats.uidStats.get(mInitiatingUid);
+ if (uidStats == null) {
+ uidStats = new long[mDescriptor.uidStatsArrayLength];
+ mPowerStats.uidStats.put(mInitiatingUid, uidStats);
+ mStatsLayout.setUidUsageDuration(uidStats, durationMs);
+ } else {
+ mStatsLayout.setUsageDuration(mPowerStats.stats,
+ mStatsLayout.getUsageDuration(mPowerStats.stats) + durationMs);
+ }
+ }
+ mLastStateTimestamp = time;
+ }
+
+ void addPowerStats(PowerComponentAggregatedPowerStats stats, PowerStats powerStats,
+ long timestampMs) {
+ ensureInitialized();
+ recordUsageDuration(timestampMs);
+ long consumedEnergy = mStatsLayout.getConsumedEnergy(powerStats.stats, 0);
+ if (consumedEnergy != BatteryStats.POWER_DATA_UNAVAILABLE) {
+ mEnergyConsumerSupported = true;
+ mStatsLayout.setConsumedEnergy(mPowerStats.stats, 0, consumedEnergy);
+ }
+
+ flushPowerStats(stats, timestampMs);
+ }
+
+ private void flushPowerStats(PowerComponentAggregatedPowerStats stats, long timestamp) {
+ mPowerStats.durationMs = timestamp - mLastUpdateTimestamp;
+ stats.addPowerStats(mPowerStats, timestamp);
+
+ Arrays.fill(mPowerStats.stats, 0);
+ mPowerStats.uidStats.clear();
+ mLastUpdateTimestamp = timestamp;
+ }
+
+ private static class Intermediates {
+ public long duration;
+ public double power;
+ }
+
+ @Override
+ void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
+ recordUsageDuration(timestampMs);
+ flushPowerStats(stats, timestampMs);
+
+ if (mPlan == null) {
+ mPlan = new PowerEstimationPlan(stats.getConfig());
+ }
+
+ computeDevicePowerEstimates(stats);
+ combineDevicePowerEstimates(stats);
+
+ List<Integer> uids = new ArrayList<>();
+ stats.collectUids(uids);
+
+ computeUidActivityTotals(stats, uids);
+ computeUidPowerEstimates(stats, uids);
+ }
+
+ private void computeDevicePowerEstimates(PowerComponentAggregatedPowerStats stats) {
+ for (int i = mPlan.deviceStateEstimations.size() - 1; i >= 0; i--) {
+ DeviceStateEstimation estimation = mPlan.deviceStateEstimations.get(i);
+ if (!stats.getDeviceStats(mTmpDeviceStatsArray, estimation.stateValues)) {
+ continue;
+ }
+
+ long duration = mStatsLayout.getUsageDuration(mTmpDeviceStatsArray);
+ if (duration > 0) {
+ double power;
+ if (mEnergyConsumerSupported) {
+ power = uCtoMah(mStatsLayout.getConsumedEnergy(mTmpDeviceStatsArray, 0));
+ } else {
+ power = mUsageBasedPowerEstimator.calculatePower(duration);
+ }
+ mStatsLayout.setDevicePowerEstimate(mTmpDeviceStatsArray, power);
+ stats.setDeviceStats(estimation.stateValues, mTmpDeviceStatsArray);
+ }
+ }
+ }
+
+ private void combineDevicePowerEstimates(PowerComponentAggregatedPowerStats stats) {
+ for (int i = mPlan.combinedDeviceStateEstimations.size() - 1; i >= 0; i--) {
+ CombinedDeviceStateEstimate estimation =
+ mPlan.combinedDeviceStateEstimations.get(i);
+ Intermediates intermediates = new Intermediates();
+ estimation.intermediates = intermediates;
+ for (int j = estimation.deviceStateEstimations.size() - 1; j >= 0; j--) {
+ DeviceStateEstimation deviceStateEstimation =
+ estimation.deviceStateEstimations.get(j);
+ if (!stats.getDeviceStats(mTmpDeviceStatsArray,
+ deviceStateEstimation.stateValues)) {
+ continue;
+ }
+ intermediates.power += mStatsLayout.getDevicePowerEstimate(mTmpDeviceStatsArray);
+ }
+ }
+ }
+
+ private void computeUidActivityTotals(PowerComponentAggregatedPowerStats stats,
+ List<Integer> uids) {
+ for (int i = mPlan.uidStateEstimates.size() - 1; i >= 0; i--) {
+ UidStateEstimate uidStateEstimate = mPlan.uidStateEstimates.get(i);
+ Intermediates intermediates =
+ (Intermediates) uidStateEstimate.combinedDeviceStateEstimate.intermediates;
+ for (int j = uids.size() - 1; j >= 0; j--) {
+ int uid = uids.get(j);
+ for (UidStateProportionalEstimate proportionalEstimate :
+ uidStateEstimate.proportionalEstimates) {
+ if (stats.getUidStats(mTmpUidStatsArray, uid,
+ proportionalEstimate.stateValues)) {
+ intermediates.duration +=
+ mStatsLayout.getUidUsageDuration(mTmpUidStatsArray);
+ }
+ }
+ }
+ }
+ }
+
+ private void computeUidPowerEstimates(PowerComponentAggregatedPowerStats stats,
+ List<Integer> uids) {
+ for (int i = mPlan.uidStateEstimates.size() - 1; i >= 0; i--) {
+ UidStateEstimate uidStateEstimate = mPlan.uidStateEstimates.get(i);
+ Intermediates intermediates =
+ (Intermediates) uidStateEstimate.combinedDeviceStateEstimate.intermediates;
+ if (intermediates.duration == 0) {
+ continue;
+ }
+ List<UidStateProportionalEstimate> proportionalEstimates =
+ uidStateEstimate.proportionalEstimates;
+ for (int j = proportionalEstimates.size() - 1; j >= 0; j--) {
+ UidStateProportionalEstimate proportionalEstimate = proportionalEstimates.get(j);
+ for (int k = uids.size() - 1; k >= 0; k--) {
+ int uid = uids.get(k);
+ if (stats.getUidStats(mTmpUidStatsArray, uid,
+ proportionalEstimate.stateValues)) {
+ double power = intermediates.power
+ * mStatsLayout.getUidUsageDuration(mTmpUidStatsArray)
+ / intermediates.duration;
+ mStatsLayout.setUidPowerEstimate(mTmpUidStatsArray, power);
+ stats.setUidStats(uid, proportionalEstimate.stateValues,
+ mTmpUidStatsArray);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/power/stats/BluetoothPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/BluetoothPowerStatsProcessor.java
index 4d6db97..077b057 100644
--- a/services/core/java/com/android/server/power/stats/BluetoothPowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/BluetoothPowerStatsProcessor.java
@@ -86,7 +86,7 @@
}
@Override
- void finish(PowerComponentAggregatedPowerStats stats) {
+ void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
if (stats.getPowerStatsDescriptor() == null) {
return;
}
diff --git a/services/core/java/com/android/server/power/stats/CpuPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/CpuPowerStatsProcessor.java
index 57b7259..6da0a8f 100644
--- a/services/core/java/com/android/server/power/stats/CpuPowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/CpuPowerStatsProcessor.java
@@ -138,7 +138,7 @@
}
@Override
- public void finish(PowerComponentAggregatedPowerStats stats) {
+ public void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
if (stats.getPowerStatsDescriptor() == null) {
return;
}
diff --git a/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsProcessor.java
index eebed2f..dcce562 100644
--- a/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsProcessor.java
@@ -166,7 +166,7 @@
}
@Override
- void finish(PowerComponentAggregatedPowerStats stats) {
+ void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
if (stats.getPowerStatsDescriptor() == null) {
return;
}
diff --git a/services/core/java/com/android/server/power/stats/MultiStateStats.java b/services/core/java/com/android/server/power/stats/MultiStateStats.java
index a822281..c3a0aeb 100644
--- a/services/core/java/com/android/server/power/stats/MultiStateStats.java
+++ b/services/core/java/com/android/server/power/stats/MultiStateStats.java
@@ -41,6 +41,7 @@
private static final String TAG = "MultiStateStats";
private static final String XML_TAG_STATS = "stats";
+ public static final int STATE_DOES_NOT_EXIST = -1;
/**
* A set of states, e.g. on-battery, screen-on, procstate. The state values are integers
@@ -70,6 +71,18 @@
}
/**
+ * Finds state by name in the provided array. If not found, returns STATE_DOES_NOT_EXIST.
+ */
+ public static int findTrackedStateByName(MultiStateStats.States[] states, String name) {
+ for (int i = 0; i < states.length; i++) {
+ if (states[i].getName().equals(name)) {
+ return i;
+ }
+ }
+ return STATE_DOES_NOT_EXIST;
+ }
+
+ /**
* Iterates over all combinations of tracked states and invokes <code>consumer</code>
* for each of them.
*/
diff --git a/services/core/java/com/android/server/power/stats/PhoneCallPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/PhoneCallPowerStatsProcessor.java
index 5c545fd..ec23fa0 100644
--- a/services/core/java/com/android/server/power/stats/PhoneCallPowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/PhoneCallPowerStatsProcessor.java
@@ -39,7 +39,7 @@
}
@Override
- void finish(PowerComponentAggregatedPowerStats stats) {
+ void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
stats.setPowerStatsDescriptor(mDescriptor);
PowerComponentAggregatedPowerStats mobileRadioStats =
diff --git a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
index 0528733..85a2293 100644
--- a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
+++ b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
@@ -16,6 +16,8 @@
package com.android.server.power.stats;
+import static com.android.server.power.stats.MultiStateStats.STATE_DOES_NOT_EXIST;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.UserHandle;
@@ -68,10 +70,12 @@
private MultiStateStats mDeviceStats;
private final SparseArray<MultiStateStats> mStateStats = new SparseArray<>();
private final SparseArray<UidStats> mUidStats = new SparseArray<>();
+ private long[] mZeroArray;
private static class UidStats {
public int[] states;
public MultiStateStats stats;
+ public boolean updated;
}
PowerComponentAggregatedPowerStats(@NonNull AggregatedPowerStats aggregatedPowerStats,
@@ -122,16 +126,18 @@
}
}
- if (mUidStateConfig[stateId].isTracked()) {
+ int uidStateId = MultiStateStats.States
+ .findTrackedStateByName(mUidStateConfig, mDeviceStateConfig[stateId].getName());
+ if (uidStateId != STATE_DOES_NOT_EXIST && mUidStateConfig[uidStateId].isTracked()) {
for (int i = mUidStats.size() - 1; i >= 0; i--) {
PowerComponentAggregatedPowerStats.UidStats uidStats = mUidStats.valueAt(i);
if (uidStats.stats == null) {
createUidStats(uidStats, timestampMs);
}
- uidStats.states[stateId] = state;
+ uidStats.states[uidStateId] = state;
if (uidStats.stats != null) {
- uidStats.stats.setState(stateId, state, timestampMs);
+ uidStats.stats.setState(uidStateId, state, timestampMs);
}
}
}
@@ -196,6 +202,22 @@
createUidStats(uidStats, timestampMs);
}
uidStats.stats.increment(powerStats.uidStats.valueAt(i), timestampMs);
+ uidStats.updated = true;
+ }
+
+ // For UIDs not mentioned in the PowerStats object, we must assume a 0 increment.
+ // It is essential to call `stats.increment(zero)` in order to record the new
+ // timestamp, which will ensure correct proportional attribution across all UIDs
+ for (int i = mUidStats.size() - 1; i >= 0; i--) {
+ PowerComponentAggregatedPowerStats.UidStats uidStats = mUidStats.valueAt(i);
+ if (!uidStats.updated && uidStats.stats != null) {
+ if (mZeroArray == null
+ || mZeroArray.length != mPowerStatsDescriptor.uidStatsArrayLength) {
+ mZeroArray = new long[mPowerStatsDescriptor.uidStatsArrayLength];
+ }
+ uidStats.stats.increment(mZeroArray, timestampMs);
+ }
+ uidStats.updated = false;
}
mPowerStatsTimestamp = timestampMs;
@@ -217,10 +239,13 @@
uidStats = new UidStats();
uidStats.states = new int[mUidStateConfig.length];
for (int stateId = 0; stateId < mUidStateConfig.length; stateId++) {
- if (mUidStateConfig[stateId].isTracked()
- && stateId < mDeviceStateConfig.length
- && mDeviceStateConfig[stateId].isTracked()) {
- uidStats.states[stateId] = mDeviceStates[stateId];
+ if (mUidStateConfig[stateId].isTracked()) {
+ int deviceStateId = MultiStateStats.States.findTrackedStateByName(
+ mDeviceStateConfig, mUidStateConfig[stateId].getName());
+ if (deviceStateId != STATE_DOES_NOT_EXIST
+ && mDeviceStateConfig[deviceStateId].isTracked()) {
+ uidStats.states[stateId] = mDeviceStates[deviceStateId];
+ }
}
}
mUidStats.put(uid, uidStats);
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
index 6a4c1f0..6e7fdf1 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
@@ -71,9 +71,13 @@
mStats = new AggregatedPowerStats(mAggregatedPowerStatsConfig);
}
+ start(mStats, startTimeMs);
+
boolean clockUpdateAdded = false;
long baseTime = startTimeMs > 0 ? startTimeMs : UNINITIALIZED;
long lastTime = 0;
+ int lastStates = 0xFFFFFFFF;
+ int lastStates2 = 0xFFFFFFFF;
try (BatteryStatsHistoryIterator iterator = mHistory.iterate(startTimeMs, endTimeMs)) {
while (iterator.hasNext()) {
BatteryStats.HistoryItem item = iterator.next();
@@ -111,6 +115,19 @@
mCurrentScreenState = screenState;
}
+ if ((item.states
+ & BatteryStats.HistoryItem.IMPORTANT_FOR_POWER_STATS_STATES)
+ != lastStates
+ || (item.states2
+ & BatteryStats.HistoryItem.IMPORTANT_FOR_POWER_STATS_STATES2)
+ != lastStates2) {
+ mStats.noteStateChange(item);
+ lastStates = item.states
+ & BatteryStats.HistoryItem.IMPORTANT_FOR_POWER_STATS_STATES;
+ lastStates2 = item.states2
+ & BatteryStats.HistoryItem.IMPORTANT_FOR_POWER_STATS_STATES2;
+ }
+
if (item.processStateChange != null) {
mStats.setUidState(item.processStateChange.uid,
AggregatedPowerStatsConfig.STATE_PROCESS_STATE,
@@ -121,7 +138,7 @@
if (!mStats.isCompatible(item.powerStats)) {
if (lastTime > baseTime) {
mStats.setDuration(lastTime - baseTime);
- finish(mStats);
+ finish(mStats, lastTime);
consumer.accept(mStats);
}
mStats.reset();
@@ -134,7 +151,7 @@
}
if (lastTime > baseTime) {
mStats.setDuration(lastTime - baseTime);
- finish(mStats);
+ finish(mStats, lastTime);
consumer.accept(mStats);
}
@@ -142,12 +159,22 @@
}
}
- private void finish(AggregatedPowerStats stats) {
+ private void start(AggregatedPowerStats stats, long timestampMs) {
for (int i = 0; i < mProcessors.size(); i++) {
PowerComponentAggregatedPowerStats component =
stats.getPowerComponentStats(mProcessors.keyAt(i));
if (component != null) {
- mProcessors.valueAt(i).finish(component);
+ mProcessors.valueAt(i).start(component, timestampMs);
+ }
+ }
+ }
+
+ private void finish(AggregatedPowerStats stats, long timestampMs) {
+ for (int i = 0; i < mProcessors.size(); i++) {
+ PowerComponentAggregatedPowerStats component =
+ stats.getPowerComponentStats(mProcessors.keyAt(i));
+ if (component != null) {
+ mProcessors.valueAt(i).finish(component, timestampMs);
}
}
}
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsLayout.java b/services/core/java/com/android/server/power/stats/PowerStatsLayout.java
index 58efd94..9624fd2 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsLayout.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsLayout.java
@@ -31,6 +31,7 @@
private static final String EXTRA_DEVICE_DURATION_POSITION = "dd";
private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION = "de";
private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT = "dec";
+ private static final String EXTRA_UID_DURATION_POSITION = "ud";
private static final String EXTRA_UID_POWER_POSITION = "up";
protected static final int UNSUPPORTED = -1;
@@ -51,6 +52,7 @@
private int mDeviceEnergyConsumerPosition;
private int mDeviceEnergyConsumerCount;
private int mDevicePowerEstimatePosition = UNSUPPORTED;
+ private int mUidDurationPosition = UNSUPPORTED;
private int mUidPowerEstimatePosition = UNSUPPORTED;
public PowerStatsLayout() {
@@ -158,7 +160,8 @@
* PowerStatsService.
*/
public void addDeviceSectionEnergyConsumers(int energyConsumerCount) {
- mDeviceEnergyConsumerPosition = addDeviceSection(energyConsumerCount, "energy");
+ mDeviceEnergyConsumerPosition = addDeviceSection(energyConsumerCount, "energy",
+ FLAG_OPTIONAL);
mDeviceEnergyConsumerCount = energyConsumerCount;
}
@@ -206,6 +209,13 @@
}
/**
+ * Declare that the UID stats array has a section capturing usage duration
+ */
+ public void addUidSectionUsageDuration() {
+ mUidDurationPosition = addUidSection(1, "time");
+ }
+
+ /**
* Declare that the UID stats array has a section capturing a power estimate
*/
public void addUidSectionPowerEstimate() {
@@ -220,6 +230,20 @@
}
/**
+ * Saves usage duration it in the corresponding element of <code>stats</code>.
+ */
+ public void setUidUsageDuration(long[] stats, long durationMs) {
+ stats[mUidDurationPosition] = durationMs;
+ }
+
+ /**
+ * Extracts the usage duration from a UID stats array.
+ */
+ public long getUidUsageDuration(long[] stats) {
+ return stats[mUidDurationPosition];
+ }
+
+ /**
* Converts the supplied mAh power estimate to a long and saves it in the corresponding
* element of <code>stats</code>.
*/
@@ -244,6 +268,7 @@
extras.putInt(EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT,
mDeviceEnergyConsumerCount);
extras.putInt(EXTRA_DEVICE_POWER_POSITION, mDevicePowerEstimatePosition);
+ extras.putInt(EXTRA_UID_DURATION_POSITION, mUidDurationPosition);
extras.putInt(EXTRA_UID_POWER_POSITION, mUidPowerEstimatePosition);
extras.putString(PowerStats.Descriptor.EXTRA_DEVICE_STATS_FORMAT, mDeviceFormat.toString());
extras.putString(PowerStats.Descriptor.EXTRA_STATE_STATS_FORMAT, mStateFormat.toString());
@@ -258,6 +283,7 @@
mDeviceEnergyConsumerPosition = extras.getInt(EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION);
mDeviceEnergyConsumerCount = extras.getInt(EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT);
mDevicePowerEstimatePosition = extras.getInt(EXTRA_DEVICE_POWER_POSITION);
+ mUidDurationPosition = extras.getInt(EXTRA_UID_DURATION_POSITION);
mUidPowerEstimatePosition = extras.getInt(EXTRA_UID_POWER_POSITION);
}
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java
index 2fd0b9a..f257e1a 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java
@@ -15,10 +15,16 @@
*/
package com.android.server.power.stats;
+import static com.android.server.power.stats.MultiStateStats.STATE_DOES_NOT_EXIST;
+import static com.android.server.power.stats.MultiStateStats.States.findTrackedStateByName;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.BatteryStats;
import android.util.Log;
+import com.android.internal.os.PowerStats;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -40,10 +46,21 @@
abstract class PowerStatsProcessor {
private static final String TAG = "PowerStatsProcessor";
- private static final int INDEX_DOES_NOT_EXIST = -1;
private static final double MILLIAMPHOUR_PER_MICROCOULOMB = 1.0 / 1000.0 / 60.0 / 60.0;
- abstract void finish(PowerComponentAggregatedPowerStats stats);
+ void start(PowerComponentAggregatedPowerStats stats, long timestampMs) {
+ }
+
+ void noteStateChange(PowerComponentAggregatedPowerStats stats,
+ BatteryStats.HistoryItem item) {
+ }
+
+ void addPowerStats(PowerComponentAggregatedPowerStats stats, PowerStats powerStats,
+ long timestampMs) {
+ stats.addPowerStats(powerStats, timestampMs);
+ }
+
+ abstract void finish(PowerComponentAggregatedPowerStats stats, long timestampMs);
protected static class PowerEstimationPlan {
private final AggregatedPowerStatsConfig.PowerComponent mConfig;
@@ -79,7 +96,7 @@
}
int index = findTrackedStateByName(uidStateConfig, deviceStateConfig[i].getName());
- if (index != INDEX_DOES_NOT_EXIST && uidStateConfig[index].isTracked()) {
+ if (index != STATE_DOES_NOT_EXIST && uidStateConfig[index].isTracked()) {
deviceStatesTrackedPerUid[i] = deviceStateConfig[i];
}
}
@@ -131,7 +148,7 @@
}
int index = findTrackedStateByName(deviceStateConfig, uidStateConfig[i].getName());
- if (index != INDEX_DOES_NOT_EXIST && deviceStateConfig[index].isTracked()) {
+ if (index != STATE_DOES_NOT_EXIST && deviceStateConfig[index].isTracked()) {
uidStatesTrackedForDevice[i] = uidStateConfig[i];
} else {
uidStatesNotTrackedForDevice[i] = uidStateConfig[i];
@@ -303,15 +320,6 @@
}
}
- private static int findTrackedStateByName(MultiStateStats.States[] states, String name) {
- for (int i = 0; i < states.length; i++) {
- if (states[i].getName().equals(name)) {
- return i;
- }
- }
- return INDEX_DOES_NOT_EXIST;
- }
-
@NonNull
private static String concatLabels(MultiStateStats.States[] config,
@AggregatedPowerStatsConfig.TrackedState int[] stateValues) {
diff --git a/services/core/java/com/android/server/power/stats/WifiPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/WifiPowerStatsProcessor.java
index a4a2e18..4e035c3 100644
--- a/services/core/java/com/android/server/power/stats/WifiPowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/WifiPowerStatsProcessor.java
@@ -114,7 +114,7 @@
}
@Override
- void finish(PowerComponentAggregatedPowerStats stats) {
+ void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
if (stats.getPowerStatsDescriptor() == null) {
return;
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e0e61fd..eb6262c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -315,6 +315,7 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -356,6 +357,7 @@
import android.view.Surface.Rotation;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets;
import android.view.WindowInsets.Type;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
@@ -8560,6 +8562,13 @@
if (isFixedOrientationLetterboxAllowed) {
resolveFixedOrientationConfiguration(newParentConfiguration);
}
+ // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds
+ // are already calculated in resolveFixedOrientationConfiguration.
+ // Don't apply aspect ratio if app is overridden to fullscreen by device user/manufacturer.
+ if (!isLetterboxedForFixedOrientationAndAspectRatio()
+ && !mLetterboxUiController.hasFullscreenOverride()) {
+ resolveAspectRatioRestriction(newParentConfiguration);
+ }
final CompatDisplayInsets compatDisplayInsets = getCompatDisplayInsets();
if (compatDisplayInsets != null) {
resolveSizeCompatModeConfiguration(newParentConfiguration, compatDisplayInsets);
@@ -8572,14 +8581,6 @@
if (!matchParentBounds()) {
computeConfigByResolveHint(resolvedConfig, newParentConfiguration);
}
- // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds
- // are already calculated in resolveFixedOrientationConfiguration, or if in size compat
- // mode, it should already be calculated in resolveSizeCompatModeConfiguration.
- // Don't apply aspect ratio if app is overridden to fullscreen by device user/manufacturer.
- }
- if (!isLetterboxedForFixedOrientationAndAspectRatio() && !mInSizeCompatModeForBounds
- && !mLetterboxUiController.hasFullscreenOverride()) {
- resolveAspectRatioRestriction(newParentConfiguration);
}
if (isFixedOrientationLetterboxAllowed || compatDisplayInsets != null
@@ -8801,7 +8802,7 @@
return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_FIXED_ORIENTATION;
}
// Letterbox for limited aspect ratio.
- if (mIsAspectRatioApplied) {
+ if (isLetterboxedForAspectRatioOnly()) {
return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_ASPECT_RATIO;
}
@@ -8830,13 +8831,27 @@
final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
final float screenResolvedBoundsWidth = screenResolvedBounds.width();
final float parentAppBoundsWidth = parentAppBounds.width();
+ final boolean isImmersiveMode = isImmersiveMode(parentBounds);
+ final Insets navBarInsets;
+ if (isImmersiveMode) {
+ navBarInsets = mDisplayContent.getInsetsStateController()
+ .getRawInsetsState().calculateInsets(
+ parentBounds,
+ WindowInsets.Type.navigationBars(),
+ true /* ignoreVisibility */);
+ } else {
+ navBarInsets = Insets.NONE;
+ }
// Horizontal position
int offsetX = 0;
if (parentBounds.width() != screenResolvedBoundsWidth) {
if (screenResolvedBoundsWidth <= parentAppBoundsWidth) {
float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier(
newParentConfiguration);
- offsetX = Math.max(0, (int) Math.ceil((parentAppBoundsWidth
+ // If in immersive mode, always align to right and overlap right insets (task bar)
+ // as they are transient and hidden. This removes awkward right spacing.
+ final int appWidth = (int) (parentAppBoundsWidth + navBarInsets.right);
+ offsetX = Math.max(0, (int) Math.ceil((appWidth
- screenResolvedBoundsWidth) * positionMultiplier)
// This is added to make sure that insets added inside
// CompatDisplayInsets#getContainerBounds() do not break the alignment
@@ -8856,9 +8871,8 @@
newParentConfiguration);
// If in immersive mode, always align to bottom and overlap bottom insets (nav bar,
// task bar) as they are transient and hidden. This removes awkward bottom spacing.
- final float newHeight = mDisplayContent.getDisplayPolicy().isImmersiveMode()
- ? parentBoundsHeight : parentAppBoundsHeight;
- offsetY = Math.max(0, (int) Math.ceil((newHeight
+ final int appHeight = (int) (parentAppBoundsHeight + navBarInsets.bottom);
+ offsetY = Math.max(0, (int) Math.ceil((appHeight
- screenResolvedBoundsHeight) * positionMultiplier)
// This is added to make sure that insets added inside
// CompatDisplayInsets#getContainerBounds() do not break the alignment
@@ -8878,7 +8892,8 @@
// If the top is aligned with parentAppBounds add the vertical insets back so that the app
// content aligns with the status bar
- if (resolvedConfig.windowConfiguration.getAppBounds().top == parentAppBounds.top) {
+ if (resolvedConfig.windowConfiguration.getAppBounds().top == parentAppBounds.top
+ && !isImmersiveMode) {
resolvedConfig.windowConfiguration.getBounds().top = parentBounds.top;
if (mSizeCompatBounds != null) {
mSizeCompatBounds.top = parentBounds.top;
@@ -8901,6 +8916,18 @@
}
}
+ boolean isImmersiveMode(@NonNull Rect parentBounds) {
+ if (!mResolveConfigHint.mUseOverrideInsetsForConfig) {
+ return false;
+ }
+ final Insets navBarInsets = mDisplayContent.getInsetsStateController()
+ .getRawInsetsState().calculateInsets(
+ parentBounds,
+ WindowInsets.Type.navigationBars(),
+ false /* ignoreVisibility */);
+ return Insets.NONE.equals(navBarInsets);
+ }
+
@NonNull Rect getScreenResolvedBounds() {
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
@@ -8943,6 +8970,10 @@
return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
}
+ boolean isLetterboxedForAspectRatioOnly() {
+ return mLetterboxBoundsForAspectRatio != null;
+ }
+
boolean isAspectRatioApplied() {
return mIsAspectRatioApplied;
}
@@ -9235,11 +9266,11 @@
// orientation bounds (stored in resolved bounds) instead of parent bounds since the
// activity will be displayed within them even if it is in size compat mode. They should be
// saved here before resolved bounds are overridden below.
- final Rect containerBounds = isLetterboxedForFixedOrientationAndAspectRatio()
+ final Rect containerBounds = isAspectRatioApplied()
? new Rect(resolvedBounds)
: newParentConfiguration.windowConfiguration.getBounds();
- final Rect containerAppBounds = isLetterboxedForFixedOrientationAndAspectRatio()
- ? new Rect(getResolvedOverrideConfiguration().windowConfiguration.getAppBounds())
+ final Rect containerAppBounds = isAspectRatioApplied()
+ ? new Rect(resolvedConfig.windowConfiguration.getAppBounds())
: newParentConfiguration.windowConfiguration.getAppBounds();
final int requestedOrientation = getRequestedConfigurationOrientation();
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 2cccd33..1a9d211 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -56,6 +56,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Pair;
+import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -75,6 +76,7 @@
* is no guarantee that other system services are already present.
*/
class ActivityStartInterceptor {
+ private static final String TAG = "ActivityStartInterceptor";
private final ActivityTaskManagerService mService;
private final ActivityTaskSupervisor mSupervisor;
@@ -284,6 +286,8 @@
if (!mUserManager.isQuietModeEnabled(UserHandle.of(mUserId))) {
return false;
}
+ Slog.i(TAG, "Intent : " + mIntent + " intercepted for user: " + mUserId
+ + " because quiet mode is enabled.");
IntentSender target = createIntentSenderForOriginalIntent(mCallingUid,
FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT);
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index a9450c4..eb85c1a 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -505,10 +505,10 @@
*/
boolean shouldFreezeInsetsPosition(WindowState w) {
// Non-change transition (OP_APP_SWITCH) and METHOD_BLAST don't use screenshot so the
- // insets should keep original position before the start transaction is applied.
+ // insets should keep original position before the window is done with new rotation.
return mTransitionOp != OP_LEGACY && (isSeamlessTransition()
|| TransitionController.SYNC_METHOD == BLASTSyncEngine.METHOD_BLAST)
- && !mIsStartTransactionCommitted && canBeAsync(w.mToken) && isTargetToken(w.mToken);
+ && canBeAsync(w.mToken) && isTargetToken(w.mToken);
}
/** Returns true if there won't be a screen rotation animation (screenshot-based). */
diff --git a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
index 1128328..50ac801 100644
--- a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
@@ -18,8 +18,8 @@
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.LaunchParamsModifierUtils.applyLayoutGravity;
-import static com.android.server.wm.LaunchParamsModifierUtils.calculateLayoutBounds;
+import static com.android.server.wm.LaunchParamsUtil.applyLayoutGravity;
+import static com.android.server.wm.LaunchParamsUtil.calculateLayoutBounds;
import android.annotation.NonNull;
import android.annotation.Nullable;
diff --git a/services/core/java/com/android/server/wm/LaunchParamsModifierUtils.java b/services/core/java/com/android/server/wm/LaunchParamsModifierUtils.java
deleted file mode 100644
index db54647..0000000
--- a/services/core/java/com/android/server/wm/LaunchParamsModifierUtils.java
+++ /dev/null
@@ -1,102 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.pm.ActivityInfo;
-import android.graphics.Rect;
-import android.util.Size;
-import android.view.Gravity;
-
-class LaunchParamsModifierUtils {
-
- /**
- * Calculates bounds based on window layout size manifest values. These can include width,
- * height, width fraction and height fraction. In the event only one dimension of values are
- * specified in the manifest (e.g. width but no height value), the corresponding display area
- * dimension will be used as the default value unless some desired sizes have been specified.
- */
- static void calculateLayoutBounds(@NonNull Rect stableBounds,
- @NonNull ActivityInfo.WindowLayout windowLayout, @NonNull Rect inOutBounds,
- @Nullable Size desiredSize) {
- final int defaultWidth = stableBounds.width();
- final int defaultHeight = stableBounds.height();
- int width;
- int height;
-
- if (desiredSize == null) {
- // If desired bounds have not been specified, use the exiting default bounds as the
- // desired.
- desiredSize = new Size(stableBounds.width(), stableBounds.height());
- }
-
- width = desiredSize.getWidth();
- if (windowLayout.width > 0 && windowLayout.width < defaultWidth) {
- width = windowLayout.width;
- } else if (windowLayout.widthFraction > 0 && windowLayout.widthFraction < 1.0f) {
- width = (int) (defaultWidth * windowLayout.widthFraction);
- }
-
- height = desiredSize.getHeight();
- if (windowLayout.height > 0 && windowLayout.height < defaultHeight) {
- height = windowLayout.height;
- } else if (windowLayout.heightFraction > 0 && windowLayout.heightFraction < 1.0f) {
- height = (int) (defaultHeight * windowLayout.heightFraction);
- }
-
- inOutBounds.set(0, 0, width, height);
- }
-
- /**
- * Applies a vertical and horizontal gravity on the inOutBounds in relation to the stableBounds.
- */
- static void applyLayoutGravity(int verticalGravity, int horizontalGravity,
- @NonNull Rect inOutBounds, @NonNull Rect stableBounds) {
- final int width = inOutBounds.width();
- final int height = inOutBounds.height();
-
- final float fractionOfHorizontalOffset;
- switch (horizontalGravity) {
- case Gravity.LEFT:
- fractionOfHorizontalOffset = 0f;
- break;
- case Gravity.RIGHT:
- fractionOfHorizontalOffset = 1f;
- break;
- default:
- fractionOfHorizontalOffset = 0.5f;
- }
-
- final float fractionOfVerticalOffset;
- switch (verticalGravity) {
- case Gravity.TOP:
- fractionOfVerticalOffset = 0f;
- break;
- case Gravity.BOTTOM:
- fractionOfVerticalOffset = 1f;
- break;
- default:
- fractionOfVerticalOffset = 0.5f;
- }
-
- inOutBounds.offsetTo(stableBounds.left, stableBounds.top);
- final int xOffset = (int) (fractionOfHorizontalOffset * (stableBounds.width() - width));
- final int yOffset = (int) (fractionOfVerticalOffset * (stableBounds.height() - height));
- inOutBounds.offset(xOffset, yOffset);
- }
-}
diff --git a/services/core/java/com/android/server/wm/LaunchParamsUtil.java b/services/core/java/com/android/server/wm/LaunchParamsUtil.java
index cd071af..9416daf 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsUtil.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsUtil.java
@@ -23,9 +23,11 @@
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.util.Size;
+import android.view.Gravity;
import android.view.View;
/**
@@ -195,4 +197,79 @@
}
inOutBounds.offset(dx, dy);
}
+
+ /**
+ * Calculates bounds based on window layout size manifest values. These can include width,
+ * height, width fraction and height fraction. In the event only one dimension of values are
+ * specified in the manifest (e.g. width but no height value), the corresponding display area
+ * dimension will be used as the default value unless some desired sizes have been specified.
+ */
+ static void calculateLayoutBounds(@NonNull Rect stableBounds,
+ @NonNull ActivityInfo.WindowLayout windowLayout, @NonNull Rect inOutBounds,
+ @Nullable Size desiredSize) {
+ final int defaultWidth = stableBounds.width();
+ final int defaultHeight = stableBounds.height();
+ int width;
+ int height;
+
+ if (desiredSize == null) {
+ // If desired bounds have not been specified, use the exiting default bounds as the
+ // desired.
+ desiredSize = new Size(stableBounds.width(), stableBounds.height());
+ }
+
+ width = desiredSize.getWidth();
+ if (windowLayout.width > 0 && windowLayout.width < defaultWidth) {
+ width = windowLayout.width;
+ } else if (windowLayout.widthFraction > 0 && windowLayout.widthFraction < 1.0f) {
+ width = (int) (defaultWidth * windowLayout.widthFraction);
+ }
+
+ height = desiredSize.getHeight();
+ if (windowLayout.height > 0 && windowLayout.height < defaultHeight) {
+ height = windowLayout.height;
+ } else if (windowLayout.heightFraction > 0 && windowLayout.heightFraction < 1.0f) {
+ height = (int) (defaultHeight * windowLayout.heightFraction);
+ }
+
+ inOutBounds.set(0, 0, width, height);
+ }
+
+ /**
+ * Applies a vertical and horizontal gravity on the inOutBounds in relation to the stableBounds.
+ */
+ static void applyLayoutGravity(int verticalGravity, int horizontalGravity,
+ @NonNull Rect inOutBounds, @NonNull Rect stableBounds) {
+ final int width = inOutBounds.width();
+ final int height = inOutBounds.height();
+
+ final float fractionOfHorizontalOffset;
+ switch (horizontalGravity) {
+ case Gravity.LEFT:
+ fractionOfHorizontalOffset = 0f;
+ break;
+ case Gravity.RIGHT:
+ fractionOfHorizontalOffset = 1f;
+ break;
+ default:
+ fractionOfHorizontalOffset = 0.5f;
+ }
+
+ final float fractionOfVerticalOffset;
+ switch (verticalGravity) {
+ case Gravity.TOP:
+ fractionOfVerticalOffset = 0f;
+ break;
+ case Gravity.BOTTOM:
+ fractionOfVerticalOffset = 1f;
+ break;
+ default:
+ fractionOfVerticalOffset = 0.5f;
+ }
+
+ inOutBounds.offsetTo(stableBounds.left, stableBounds.top);
+ final int xOffset = (int) (fractionOfHorizontalOffset * (stableBounds.width() - width));
+ final int yOffset = (int) (fractionOfVerticalOffset * (stableBounds.height() - height));
+ inOutBounds.offset(xOffset, yOffset);
+ }
}
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 6e11e08..b8d0694 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -1704,7 +1704,7 @@
if (mainWin.isLetterboxedForDisplayCutout()) {
return "DISPLAY_CUTOUT";
}
- if (mActivityRecord.isAspectRatioApplied()) {
+ if (mActivityRecord.isLetterboxedForAspectRatioOnly()) {
return "ASPECT_RATIO";
}
return "UNKNOWN_REASON";
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index f37638f..5c9a84d 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -40,8 +40,6 @@
import static com.android.server.wm.ActivityStarter.Request;
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.LaunchParamsModifierUtils.applyLayoutGravity;
-import static com.android.server.wm.LaunchParamsModifierUtils.calculateLayoutBounds;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -644,13 +642,13 @@
displayArea.getStableRect(stableBounds);
if (windowLayout.hasSpecifiedSize()) {
- calculateLayoutBounds(stableBounds, windowLayout, inOutBounds,
+ LaunchParamsUtil.calculateLayoutBounds(stableBounds, windowLayout, inOutBounds,
/* desiredBounds */ null);
} else if (inOutBounds.isEmpty()) {
getTaskBounds(root, displayArea, windowLayout, WINDOWING_MODE_FREEFORM,
/* hasInitialBounds */ false, inOutBounds);
}
- applyLayoutGravity(verticalGravity, horizontalGravity, inOutBounds,
+ LaunchParamsUtil.applyLayoutGravity(verticalGravity, horizontalGravity, inOutBounds,
stableBounds);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b603551..0bf1c88 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8619,8 +8619,8 @@
return true;
}
// For a task session, find the activity identified by the launch cookie.
- final WindowContainerInfo wci = getTaskWindowContainerInfoForLaunchCookie(
- incomingSession.getTokenToRecord());
+ final WindowContainerInfo wci =
+ getTaskWindowContainerInfoForRecordingSession(incomingSession);
if (wci == null) {
Slog.w(TAG, "Handling a new recording session; unable to find the "
+ "WindowContainerToken");
@@ -9082,35 +9082,58 @@
}
/**
- * Retrieve the {@link WindowContainerInfo} of the task that contains the activity started with
- * the given launch cookie.
+ * Retrieve the {@link WindowContainerInfo} of the task that was launched for MediaProjection.
*
- * @param launchCookie the launch cookie set on the {@link ActivityOptions} when starting an
- * activity
+ * @param session the {@link ContentRecordingSession} containing the launch cookie and/or
+ * task id of the Task started for capture.
* @return a token representing the task containing the activity started with the given launch
* cookie, or {@code null} if the token couldn't be found.
*/
@VisibleForTesting
@Nullable
- WindowContainerInfo getTaskWindowContainerInfoForLaunchCookie(@NonNull IBinder launchCookie) {
- // Find the activity identified by the launch cookie.
- final ActivityRecord targetActivity =
- mRoot.getActivity(activity -> activity.mLaunchCookie == launchCookie);
- if (targetActivity == null) {
- Slog.w(TAG, "Unable to find the activity for this launch cookie");
- return null;
+ WindowContainerInfo getTaskWindowContainerInfoForRecordingSession(
+ @NonNull ContentRecordingSession session) {
+ WindowContainerToken taskWindowContainerToken = null;
+ ActivityRecord targetActivity = null;
+ Task targetTask = null;
+
+ // First attempt to find the launched task by looking for the launched activity with the
+ // matching launch cookie.
+ if (session.getTokenToRecord() != null) {
+ IBinder launchCookie = session.getTokenToRecord();
+ targetActivity = mRoot.getActivity(activity -> activity.mLaunchCookie == launchCookie);
+ if (targetActivity == null) {
+ Slog.w(TAG, "Unable to find the activity for this launch cookie");
+ } else {
+ if (targetActivity.getTask() == null) {
+ Slog.w(TAG, "Unable to find the task for this launch cookie");
+ } else {
+ targetTask = targetActivity.getTask();
+ taskWindowContainerToken = targetTask.mRemoteToken.toWindowContainerToken();
+ }
+ }
}
- if (targetActivity.getTask() == null) {
- Slog.w(TAG, "Unable to find the task for this launch cookie");
- return null;
+
+ // In the case we can't find an activity with a matching launch cookie, it could be due to
+ // the launched activity being closed, but the launched task is still open, so now attempt
+ // to look for the task directly.
+ if (taskWindowContainerToken == null && session.getTaskId() != -1) {
+ int targetTaskId = session.getTaskId();
+ targetTask = mRoot.getTask(task -> task.isTaskId(targetTaskId));
+ if (targetTask == null) {
+ Slog.w(TAG, "Unable to find the task for this projection");
+ } else {
+ taskWindowContainerToken = targetTask.mRemoteToken.toWindowContainerToken();
+ }
}
- WindowContainerToken taskWindowContainerToken =
- targetActivity.getTask().mRemoteToken.toWindowContainerToken();
+
+ // If we were unable to find the launched task in either fashion, then something must have
+ // wrong (i.e. the task was closed before capture started).
if (taskWindowContainerToken == null) {
- Slog.w(TAG, "Unable to find the WindowContainerToken for " + targetActivity.getName());
+ Slog.w(TAG, "Unable to find the WindowContainerToken for ContentRecordingSession");
return null;
}
- return new WindowContainerInfo(targetActivity.getUid(), taskWindowContainerToken);
+ return new WindowContainerInfo(targetTask.effectiveUid, taskWindowContainerToken);
}
/**
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index d733762..e763c9e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -16,6 +16,7 @@
package com.android.server.devicepolicy;
+import static android.app.admin.DevicePolicyIdentifiers.PACKAGES_SUSPENDED_POLICY;
import static android.app.admin.DevicePolicyIdentifiers.USER_CONTROL_DISABLED_PACKAGES_POLICY;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_TARGET_USER_ID;
import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_UPDATE_RESULT_KEY;
@@ -78,6 +79,10 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -260,9 +265,7 @@
boolean policyEnforced = Objects.equals(
localPolicyState.getCurrentResolvedPolicy(), value);
// TODO(b/285532044): remove hack and handle properly
- if (!policyEnforced
- && policyDefinition.getPolicyKey().getIdentifier().equals(
- USER_CONTROL_DISABLED_PACKAGES_POLICY)) {
+ if (!policyEnforced && shouldApplyPackageSetUnionPolicyHack(policyDefinition)) {
PolicyValue<Set<String>> parsedValue = (PolicyValue<Set<String>>) value;
PolicyValue<Set<String>> parsedResolvedValue =
(PolicyValue<Set<String>>) localPolicyState.getCurrentResolvedPolicy();
@@ -528,8 +531,7 @@
globalPolicyState.getCurrentResolvedPolicy(), value);
// TODO(b/285532044): remove hack and handle properly
if (!policyAppliedGlobally
- && policyDefinition.getPolicyKey().getIdentifier().equals(
- USER_CONTROL_DISABLED_PACKAGES_POLICY)) {
+ && shouldApplyPackageSetUnionPolicyHack(policyDefinition)) {
PolicyValue<Set<String>> parsedValue = (PolicyValue<Set<String>>) value;
PolicyValue<Set<String>> parsedResolvedValue =
(PolicyValue<Set<String>>) globalPolicyState.getCurrentResolvedPolicy();
@@ -666,8 +668,7 @@
}
// TODO(b/285532044): remove hack and handle properly
- if (policyDefinition.getPolicyKey().getIdentifier().equals(
- USER_CONTROL_DISABLED_PACKAGES_POLICY)) {
+ if (shouldApplyPackageSetUnionPolicyHack(policyDefinition)) {
if (!Objects.equals(value, localPolicyState.getCurrentResolvedPolicy())) {
PolicyValue<Set<String>> parsedValue = (PolicyValue<Set<String>>) value;
PolicyValue<Set<String>> parsedResolvedValue =
@@ -688,6 +689,12 @@
*/
@Nullable
<V> V getResolvedPolicy(@NonNull PolicyDefinition<V> policyDefinition, int userId) {
+ PolicyValue<V> resolvedValue = getResolvedPolicyValue(policyDefinition, userId);
+ return resolvedValue == null ? null : resolvedValue.getValue();
+ }
+
+ private <V> PolicyValue<V> getResolvedPolicyValue(@NonNull PolicyDefinition<V> policyDefinition,
+ int userId) {
Objects.requireNonNull(policyDefinition);
synchronized (mLock) {
@@ -699,11 +706,39 @@
resolvedValue = getGlobalPolicyStateLocked(
policyDefinition).getCurrentResolvedPolicy();
}
- return resolvedValue == null ? null : resolvedValue.getValue();
+ return resolvedValue;
}
}
/**
+ * Retrieves resolved policy for the provided {@code policyDefinition} and a list of
+ * users.
+ */
+ @Nullable
+ <V> V getResolvedPolicyAcrossUsers(@NonNull PolicyDefinition<V> policyDefinition,
+ List<Integer> users) {
+ Objects.requireNonNull(policyDefinition);
+
+ List<PolicyValue<V>> adminPolicies = new ArrayList<>();
+ synchronized (mLock) {
+ for (int userId : users) {
+ PolicyValue<V> resolvedValue = getResolvedPolicyValue(policyDefinition, userId);
+ if (resolvedValue != null) {
+ adminPolicies.add(resolvedValue);
+ }
+ }
+ }
+ // We will be aggregating PolicyValue across multiple admins across multiple users,
+ // including different policies set by the same admin on different users. This is
+ // not supported by ResolutionMechanism generically, instead we need to call the special
+ // resolve() method that doesn't care about admins who set the policy. Note that not every
+ // ResolutionMechanism supports this.
+ PolicyValue<V> resolvedValue =
+ policyDefinition.getResolutionMechanism().resolve(adminPolicies);
+ return resolvedValue == null ? null : resolvedValue.getValue();
+ }
+
+ /**
* Retrieves the policy set by the admin for the provided {@code policyDefinition} and
* {@code userId} if one was set, otherwise returns {@code null}.
*/
@@ -1743,6 +1778,18 @@
}
}
+ /**
+ * Create a backup of the policy engine XML file, so that we can recover previous state
+ * in case some data-loss bug is triggered e.g. during migration.
+ *
+ * Backup is only created if one with the same ID does not exist yet.
+ */
+ void createBackup(String backupId) {
+ synchronized (mLock) {
+ DevicePoliciesReaderWriter.createBackup(backupId);
+ }
+ }
+
<V> void reapplyAllPoliciesOnBootLocked() {
for (PolicyKey policy : mGlobalPolicies.keySet()) {
PolicyState<?> policyState = mGlobalPolicies.get(policy);
@@ -1820,8 +1867,22 @@
return false;
}
+ /**
+ * For PackageSetUnion policies, we can't simply compare the resolved policy against the admin's
+ * policy for equality to determine if the admin has applied the policy successfully, instead
+ * the admin's policy should be considered applied successfully as long as its policy is subset
+ * of the resolved policy. This method controls which policies should use this special logic.
+ */
+ private <V> boolean shouldApplyPackageSetUnionPolicyHack(PolicyDefinition<V> policy) {
+ String policyKey = policy.getPolicyKey().getIdentifier();
+ return policyKey.equals(USER_CONTROL_DISABLED_PACKAGES_POLICY)
+ || policyKey.equals(PACKAGES_SUSPENDED_POLICY);
+ }
+
private class DevicePoliciesReaderWriter {
private static final String DEVICE_POLICIES_XML = "device_policy_state.xml";
+ private static final String BACKUP_DIRECTORY = "device_policy_backups";
+ private static final String BACKUP_FILENAME = "device_policy_state.%s.xml";
private static final String TAG_LOCAL_POLICY_ENTRY = "local-policy-entry";
private static final String TAG_GLOBAL_POLICY_ENTRY = "global-policy-entry";
private static final String TAG_POLICY_STATE_ENTRY = "policy-state-entry";
@@ -1836,8 +1897,30 @@
private final File mFile;
+ private static File getFileName() {
+ return new File(Environment.getDataSystemDirectory(), DEVICE_POLICIES_XML);
+ }
private DevicePoliciesReaderWriter() {
- mFile = new File(Environment.getDataSystemDirectory(), DEVICE_POLICIES_XML);
+ mFile = getFileName();
+ }
+
+ public static void createBackup(String backupId) {
+ try {
+ File backupDirectory = new File(Environment.getDataSystemDirectory(),
+ BACKUP_DIRECTORY);
+ backupDirectory.mkdir();
+ Path backupPath = Path.of(backupDirectory.getPath(),
+ BACKUP_FILENAME.formatted(backupId));
+ if (backupPath.toFile().exists()) {
+ Log.w(TAG, "Backup already exist: " + backupPath);
+ } else {
+ Files.copy(getFileName().toPath(), backupPath,
+ StandardCopyOption.REPLACE_EXISTING);
+ Log.i(TAG, "Backup created at " + backupPath);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Cannot create backup " + backupId, e);
+ }
}
void writeToFileLocked() {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 5bf5efd..bdd0730 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -569,6 +569,7 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -2221,32 +2222,6 @@
return packageNameAndSignature;
}
- private void unsuspendAppsForQuietProfiles() {
- PackageManagerInternal pmi = mInjector.getPackageManagerInternal();
- List<UserInfo> users = mUserManagerInternal.getUsers(true /* excludeDying */);
-
- for (UserInfo user : users) {
- if (!user.isManagedProfile() || !user.isQuietModeEnabled()) {
- continue;
- }
- int userId = user.id;
- var suspendedByAdmin = getPackagesSuspendedByAdmin(userId);
- var packagesToUnsuspend = mInjector.getPackageManager(userId)
- .getInstalledPackages(PackageManager.PackageInfoFlags.of(
- MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE))
- .stream()
- .map(packageInfo -> packageInfo.packageName)
- .filter(pkg -> !suspendedByAdmin.contains(pkg))
- .toArray(String[]::new);
-
- Slogf.i(LOG_TAG, "Unsuspending work apps for user %d", userId);
- // When app suspension was used for quiet mode, the apps were suspended by platform
- // package, just like when admin suspends them. So although it wasn't admin who
- // suspended, this method will remove the right suspension record.
- pmi.setPackagesSuspendedByAdmin(userId, packagesToUnsuspend, false /* suspended */);
- }
- }
-
private Owners makeOwners(Injector injector, PolicyPathProvider pathProvider) {
return new Owners(
injector.getUserManager(), injector.getUserManagerInternal(),
@@ -3470,6 +3445,79 @@
new BooleanPolicyValue(true));
}
+ @GuardedBy("getLockObject()")
+ private boolean maybeMigrateRequiredPasswordComplexityLocked(String backupId) {
+ Slog.i(LOG_TAG, "Migrating password complexity to policy engine");
+ if (!Flags.unmanagedModeMigration()) {
+ return false;
+ }
+ if (mOwners.isRequiredPasswordComplexityMigrated()) {
+ return false;
+ }
+ // Create backup if none exists
+ mDevicePolicyEngine.createBackup(backupId);
+ try {
+ iterateThroughDpcAdminsLocked((admin, enforcingAdmin) -> {
+ int userId = enforcingAdmin.getUserId();
+ if (admin.mPasswordComplexity != PASSWORD_COMPLEXITY_NONE) {
+ mDevicePolicyEngine.setLocalPolicy(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ enforcingAdmin,
+ new IntegerPolicyValue(admin.mPasswordComplexity),
+ userId);
+ }
+ ActiveAdmin parentAdmin = admin.getParentActiveAdmin();
+ if (parentAdmin != null
+ && parentAdmin.mPasswordComplexity != PASSWORD_COMPLEXITY_NONE) {
+ mDevicePolicyEngine.setLocalPolicy(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ enforcingAdmin,
+ new IntegerPolicyValue(parentAdmin.mPasswordComplexity),
+ getProfileParentId(userId));
+ }
+ });
+ } catch (Exception e) {
+ Slog.wtf(LOG_TAG, "Failed to migrate password complexity to policy engine", e);
+ }
+
+ Slog.i(LOG_TAG, "Marking password complexity migration complete");
+ mOwners.markRequiredPasswordComplexityMigrated();
+ return true;
+ }
+
+ @GuardedBy("getLockObject()")
+ private boolean maybeMigrateSuspendedPackagesLocked(String backupId) {
+ Slog.i(LOG_TAG, "Migrating suspended packages to policy engine");
+ if (!Flags.unmanagedModeMigration()) {
+ return false;
+ }
+ if (mOwners.isSuspendedPackagesMigrated()) {
+ return false;
+ }
+ // Create backup if none exists
+ mDevicePolicyEngine.createBackup(backupId);
+ try {
+ iterateThroughDpcAdminsLocked((admin, enforcingAdmin) -> {
+ if (admin.suspendedPackages == null || admin.suspendedPackages.size() == 0) {
+ return;
+ }
+ int userId = enforcingAdmin.getUserId();
+ mDevicePolicyEngine.setLocalPolicy(
+ PolicyDefinition.PACKAGES_SUSPENDED,
+ enforcingAdmin,
+ new PackageSetPolicyValue(new ArraySet<>(admin.suspendedPackages)),
+ userId);
+ });
+ } catch (Exception e) {
+ Slog.wtf(LOG_TAG, "Failed to migrate suspended packages to policy engine", e);
+ }
+
+ Slog.i(LOG_TAG, "Marking suspended packages migration complete");
+ mOwners.markSuspendedPackagesMigrated();
+ return true;
+ }
+
+
private void applyManagedSubscriptionsPolicyIfRequired() {
int copeProfileUserId = getOrganizationOwnedProfileUserId();
// This policy is relevant only for COPE devices.
@@ -4254,27 +4302,50 @@
}
final int userId = caller.getUserId();
+ EnforcingAdmin enforcingAdmin = null;
synchronized (getLockObject()) {
ActiveAdmin ap = getActiveAdminForCallerLocked(
who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
+ if (Flags.unmanagedModeMigration()) {
+ enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who,
+ userId,
+ getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD));
+ }
// If setPasswordQuality is called on the parent, ensure that
// the primary admin does not have password complexity state (this is an
// unsupported state).
if (parent) {
- final ActiveAdmin primaryAdmin = getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, false);
- final boolean hasComplexitySet =
- primaryAdmin.mPasswordComplexity != PASSWORD_COMPLEXITY_NONE;
+ final boolean hasComplexitySet;
+ if (Flags.unmanagedModeMigration()) {
+ Integer complexity = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ enforcingAdmin,
+ userId);
+ hasComplexitySet = complexity != null && complexity != PASSWORD_COMPLEXITY_NONE;
+ } else {
+ final ActiveAdmin primaryAdmin = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, false);
+ hasComplexitySet = primaryAdmin.mPasswordComplexity != PASSWORD_COMPLEXITY_NONE;
+ }
+
Preconditions.checkState(!hasComplexitySet,
"Cannot set password quality when complexity is set on the primary admin."
+ " Set the primary admin's complexity to NONE first.");
}
+ final EnforcingAdmin enforcingAdminFinal = enforcingAdmin;
mInjector.binderWithCleanCallingIdentity(() -> {
final PasswordPolicy passwordPolicy = ap.mPasswordPolicy;
if (passwordPolicy.quality != quality) {
passwordPolicy.quality = quality;
- ap.mPasswordComplexity = PASSWORD_COMPLEXITY_NONE;
+ if (Flags.unmanagedModeMigration()) {
+ int affectedUser = parent ? getProfileParentId(userId) : userId;
+ mDevicePolicyEngine.removeLocalPolicy(PolicyDefinition.PASSWORD_COMPLEXITY,
+ enforcingAdminFinal, affectedUser);
+ } else {
+ ap.mPasswordComplexity = PASSWORD_COMPLEXITY_NONE;
+ }
resetInactivePasswordRequirementsIfRPlus(userId, ap);
updatePasswordValidityCheckpointLocked(userId, parent);
updatePasswordQualityCacheForUserGroup(userId);
@@ -4405,6 +4476,10 @@
}
}
+ /**
+ * @deprecated use {@link #getResolvedLockscreenPolicy(PolicyDefinition, int)} for
+ * coexistable policies
+ */
@GuardedBy("getLockObject()")
private List<ActiveAdmin> getActiveAdminsForLockscreenPoliciesLocked(int userHandle) {
if (isSeparateProfileChallengeEnabled(userHandle)) {
@@ -4428,6 +4503,25 @@
}
/**
+ * Returns a user's resolved lockscreen policy from all admins. This is different from normal
+ * policy resolution because if the specified user has a work profile with unified challenge,
+ * all policies set on the profile will also affect that user.
+ */
+ private <V> V getResolvedLockscreenPolicy(PolicyDefinition<V> policyDefinition, int userId) {
+ if (isSeparateProfileChallengeEnabled(userId)) {
+ // If this profile has a separate challenge, only return policies targeting itself.
+ return mDevicePolicyEngine.getResolvedPolicy(policyDefinition, userId);
+ }
+ // Otherwise, this user is either a full user, or it's a profile with unified challenge.
+ // In both cases we query the parent user who owns the credential (the parent user of a full
+ // user is itself), plus any profile of the parent user who has unified challenge since
+ // the policy of a unified challenge profile is enforced on the parent.
+ return getResolvedPolicyForUserAndItsManagedProfiles(policyDefinition,
+ getProfileParentId(userId),
+ (user) -> mLockPatternUtils.isProfileWithUnifiedChallenge(user.id));
+
+ }
+ /**
* Get the list of active admins for an affected user:
* <ul>
* <li>The active admins associated with the userHandle itself</li>
@@ -4460,6 +4554,9 @@
* profile associated with the given user. Optionally also include the admin of each managed
* profile.
* <p> Should not be called on a profile user.
+ *
+ * For coexistable policy, please use
+ * {@link #getResolvedPolicyForUserAndItsManagedProfiles(PolicyDefinition, int, Predicate)}
*/
@GuardedBy("getLockObject()")
private List<ActiveAdmin> getActiveAdminsForUserAndItsManagedProfilesLocked(int userHandle,
@@ -4486,6 +4583,23 @@
return admins;
}
+ private <V> V getResolvedPolicyForUserAndItsManagedProfiles(
+ PolicyDefinition<V> policyDefinition, int userHandle,
+ Predicate<UserInfo> shouldIncludeProfile) {
+ List<Integer> users = new ArrayList<>();
+
+ mInjector.binderWithCleanCallingIdentity(() -> {
+ for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
+ if (userInfo.id == userHandle) {
+ users.add(userInfo.id);
+ } else if (userInfo.isManagedProfile() && shouldIncludeProfile.test(userInfo)) {
+ users.add(userInfo.id);
+ }
+ }
+ });
+ return mDevicePolicyEngine.getResolvedPolicyAcrossUsers(policyDefinition, users);
+ }
+
/**
* Returns the list of admins on the given user, as well as parent admins for each managed
* profile associated with the given user. Optionally also include the admin of each managed
@@ -5266,13 +5380,30 @@
/* shouldIncludeProfileAdmins */ (user) -> user.id == profileUser
|| !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id));
ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>(admins.size());
- int maxRequiredComplexity = PASSWORD_COMPLEXITY_NONE;
- for (ActiveAdmin admin : admins) {
- adminMetrics.add(admin.mPasswordPolicy.getMinMetrics());
- maxRequiredComplexity = Math.max(maxRequiredComplexity, admin.mPasswordComplexity);
+ if (Flags.unmanagedModeMigration()) {
+ for (ActiveAdmin admin: admins) {
+ adminMetrics.add(admin.mPasswordPolicy.getMinMetrics());
+ }
+ Integer maxRequiredComplexity = getResolvedPolicyForUserAndItsManagedProfiles(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ userHandle,
+ /* shouldIncludeProfileAdmins */ (user) -> user.id == profileUser
+ || !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id));
+ return PasswordMetrics.validatePasswordMetrics(
+ PasswordMetrics.merge(adminMetrics),
+ maxRequiredComplexity != null
+ ? maxRequiredComplexity : PASSWORD_COMPLEXITY_NONE,
+ metrics).isEmpty();
+ } else {
+ int maxRequiredComplexity = PASSWORD_COMPLEXITY_NONE;
+ for (ActiveAdmin admin : admins) {
+ adminMetrics.add(admin.mPasswordPolicy.getMinMetrics());
+ maxRequiredComplexity = Math.max(maxRequiredComplexity,
+ admin.mPasswordComplexity);
+ }
+ return PasswordMetrics.validatePasswordMetrics(PasswordMetrics.merge(adminMetrics),
+ maxRequiredComplexity, metrics).isEmpty();
}
- return PasswordMetrics.validatePasswordMetrics(PasswordMetrics.merge(adminMetrics),
- maxRequiredComplexity, metrics).isEmpty();
}
}
@@ -5363,6 +5494,76 @@
Preconditions.checkArgument(allowedModes.contains(passwordComplexity),
"Provided complexity is not one of the allowed values.");
+ if (!Flags.unmanagedModeMigration()) {
+ setRequiredPasswordComplexityPreCoexistence(callerPackageName, passwordComplexity,
+ calledOnParent);
+ return;
+ }
+
+ CallerIdentity caller = getCallerIdentity(callerPackageName);
+ int affectedUser = calledOnParent
+ ? getProfileParentId(caller.getUserId()) : caller.getUserId();
+ EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(null,
+ MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, caller.getPackageName(),
+ caller.getUserId());
+ Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
+
+ ActiveAdmin activeAdmin = admin.getActiveAdmin();
+
+ // We require the caller to explicitly clear any password quality requirements set
+ // on the parent DPM instance, to avoid the case where password requirements are
+ // specified in the form of quality on the parent but complexity on the profile
+ // itself.
+ if (!calledOnParent) {
+ final boolean hasQualityRequirementsOnParent = activeAdmin.hasParentActiveAdmin()
+ && activeAdmin.getParentActiveAdmin().mPasswordPolicy.quality
+ != PASSWORD_QUALITY_UNSPECIFIED;
+ Preconditions.checkState(!hasQualityRequirementsOnParent,
+ "Password quality is set on the parent when attempting to set password"
+ + "complexity. Clear the quality by setting the password quality "
+ + "on the parent to PASSWORD_QUALITY_UNSPECIFIED first");
+ }
+
+ if (passwordComplexity != PASSWORD_COMPLEXITY_NONE) {
+ mDevicePolicyEngine.setLocalPolicy(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ admin,
+ new IntegerPolicyValue(passwordComplexity),
+ affectedUser);
+ } else {
+ mDevicePolicyEngine.removeLocalPolicy(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ admin,
+ affectedUser);
+ }
+
+ mInjector.binderWithCleanCallingIdentity(() -> {
+ // Reset the password policy.
+ if (calledOnParent) {
+ activeAdmin.getParentActiveAdmin().mPasswordPolicy = new PasswordPolicy();
+ } else {
+ activeAdmin.mPasswordPolicy = new PasswordPolicy();
+ }
+ synchronized (getLockObject()) {
+ updatePasswordValidityCheckpointLocked(caller.getUserId(), calledOnParent);
+ }
+ updatePasswordQualityCacheForUserGroup(caller.getUserId());
+ saveSettingsLocked(caller.getUserId());
+ });
+
+
+ DevicePolicyEventLogger
+ .createEvent(DevicePolicyEnums.SET_PASSWORD_COMPLEXITY)
+ .setAdmin(caller.getPackageName())
+ .setInt(passwordComplexity)
+ .setBoolean(calledOnParent)
+ .write();
+ logPasswordComplexityRequiredIfSecurityLogEnabled(caller.getPackageName(),
+ caller.getUserId(), calledOnParent, passwordComplexity);
+ }
+
+ private void setRequiredPasswordComplexityPreCoexistence(
+ String callerPackageName, int passwordComplexity, boolean calledOnParent) {
CallerIdentity caller = getCallerIdentity(callerPackageName);
if (!isPermissionCheckFlagEnabled()) {
Preconditions.checkCallAuthorization(
@@ -5441,6 +5642,30 @@
@GuardedBy("getLockObject()")
private int getAggregatedPasswordComplexityLocked(@UserIdInt int userHandle,
boolean deviceWideOnly) {
+ if (Flags.unmanagedModeMigration()) {
+ return getAggregatedPasswordComplexity(userHandle, deviceWideOnly);
+ } else {
+ return getAggregatedPasswordComplexityPreCoexistenceLocked(userHandle, deviceWideOnly);
+ }
+ }
+
+ private int getAggregatedPasswordComplexity(@UserIdInt int userHandle, boolean deviceWideOnly) {
+ ensureLocked();
+ Integer result;
+ if (deviceWideOnly) {
+ result = getResolvedPolicyForUserAndItsManagedProfiles(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ userHandle,
+ /* shouldIncludeProfile */ (user) -> false);
+ } else {
+ result = getResolvedLockscreenPolicy(PolicyDefinition.PASSWORD_COMPLEXITY, userHandle);
+ }
+ return result != null ? result : PASSWORD_COMPLEXITY_NONE;
+ }
+
+ @GuardedBy("getLockObject()")
+ private int getAggregatedPasswordComplexityPreCoexistenceLocked(@UserIdInt int userHandle,
+ boolean deviceWideOnly) {
ensureLocked();
final List<ActiveAdmin> admins;
if (deviceWideOnly) {
@@ -5462,24 +5687,30 @@
return PASSWORD_COMPLEXITY_NONE;
}
- final CallerIdentity caller = getCallerIdentity();
-
- if (isPermissionCheckFlagEnabled()) {
+ if (Flags.unmanagedModeMigration()) {
+ final CallerIdentity caller = getCallerIdentity(callerPackageName);
int affectedUser = calledOnParent ? getProfileParentId(caller.getUserId())
: caller.getUserId();
enforcePermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
callerPackageName, affectedUser);
+
+ Integer complexity = mDevicePolicyEngine.getResolvedPolicy(
+ PolicyDefinition.PASSWORD_COMPLEXITY,
+ affectedUser);
+ return complexity != null ? complexity : PASSWORD_COMPLEXITY_NONE;
} else {
+ final CallerIdentity caller = getCallerIdentity();
+
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller) || isProfileOwner(caller));
Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
- }
- synchronized (getLockObject()) {
- final ActiveAdmin requiredAdmin = getParentOfAdminIfRequired(
- getDeviceOrProfileOwnerAdminLocked(caller.getUserId()), calledOnParent);
- return requiredAdmin.mPasswordComplexity;
+ synchronized (getLockObject()) {
+ final ActiveAdmin requiredAdmin = getParentOfAdminIfRequired(
+ getDeviceOrProfileOwnerAdminLocked(caller.getUserId()), calledOnParent);
+ return requiredAdmin.mPasswordComplexity;
+ }
}
}
@@ -9288,6 +9519,10 @@
}
}
+ // TODO: with a quick glance this logic seems incomplete that it doesn't properly handle
+ // the different behaviour between a profile with separate challenge vs a profile with
+ // unified challenge, which was part of getActiveAdminsForLockscreenPoliciesLocked()
+ // before the migration.
if (isUnicornFlagEnabled()) {
Integer features = mDevicePolicyEngine.getResolvedPolicy(
PolicyDefinition.KEYGUARD_DISABLED_FEATURES,
@@ -12983,8 +13218,7 @@
return result;
}
- @Override
- public String[] setPackagesSuspended(ComponentName who, String callerPackage,
+ private String[] setPackagesSuspendedPreCoexistence(ComponentName who, String callerPackage,
String[] packageNames, boolean suspended) {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
ActiveAdmin admin;
@@ -13065,6 +13299,78 @@
return result;
}
+ @Override
+ public String[] setPackagesSuspended(ComponentName who, String callerPackage,
+ String[] packageNames, boolean suspended) {
+ if (!Flags.unmanagedModeMigration()) {
+ return setPackagesSuspendedPreCoexistence(who, callerPackage, packageNames, suspended);
+ }
+
+ final CallerIdentity caller = getCallerIdentity(who, callerPackage);
+
+ EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
+ who,
+ MANAGE_DEVICE_POLICY_PACKAGE_STATE,
+ caller.getPackageName(),
+ caller.getUserId());
+ checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_PACKAGES_SUSPENDED);
+
+ Set<String> packages = new ArraySet<>(packageNames);
+ Set<String> suspendedPackagesBefore = mDevicePolicyEngine.getResolvedPolicy(
+ PolicyDefinition.PACKAGES_SUSPENDED, caller.getUserId());
+
+ Set<String> currentPackages = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+ PolicyDefinition.PACKAGES_SUSPENDED,
+ enforcingAdmin,
+ caller.getUserId());
+ if (currentPackages == null) currentPackages = new ArraySet<>();
+ if (suspended) {
+ currentPackages.addAll(packages);
+ } else {
+ currentPackages.removeAll(packages);
+ }
+ if (currentPackages.isEmpty()) {
+ mDevicePolicyEngine.removeLocalPolicy(
+ PolicyDefinition.PACKAGES_SUSPENDED,
+ enforcingAdmin,
+ caller.getUserId());
+ } else {
+ mDevicePolicyEngine.setLocalPolicy(
+ PolicyDefinition.PACKAGES_SUSPENDED,
+ enforcingAdmin,
+ new PackageSetPolicyValue(currentPackages),
+ caller.getUserId());
+ }
+
+ Set<String> suspendedPackagesAfter = mDevicePolicyEngine.getResolvedPolicy(
+ PolicyDefinition.PACKAGES_SUSPENDED, caller.getUserId());
+
+ PackageSuspender suspender = new PackageSuspender(
+ suspendedPackagesBefore, suspendedPackagesAfter,
+ listPolicyExemptAppsUnchecked(mContext),
+ mInjector.getPackageManagerInternal(), caller.getUserId());
+
+ String[] result;
+ synchronized (getLockObject()) {
+ long id = mInjector.binderClearCallingIdentity();
+ try {
+ result = suspended ? suspender.suspend(packages) : suspender.unsuspend(packages);
+ } finally {
+ mInjector.binderRestoreCallingIdentity(id);
+ }
+ }
+
+ DevicePolicyEventLogger
+ .createEvent(DevicePolicyEnums.SET_PACKAGES_SUSPENDED)
+ .setAdmin(caller.getPackageName())
+ .setBoolean(/* isDelegate */ who == null)
+ .setStrings(packageNames)
+ .write();
+
+ if (VERBOSE_LOG) Slogf.v(LOG_TAG, "Returning %s", Arrays.toString(result));
+ return result;
+ }
+
/**
* Returns an array containing the union of the given non-suspended packages and
* exempt apps. Assumes both parameters are non-null and non-empty.
@@ -13086,7 +13392,7 @@
public boolean isPackageSuspended(ComponentName who, String callerPackage, String packageName) {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
- if (isUnicornFlagEnabled()) {
+ if (Flags.unmanagedModeMigration()) {
enforcePermission(
MANAGE_DEVICE_POLICY_PACKAGE_STATE,
caller.getPackageName(),
@@ -15257,17 +15563,6 @@
}
}
- private Set<String> getPackagesSuspendedByAdmin(@UserIdInt int userId) {
- synchronized (getLockObject()) {
- ActiveAdmin admin = getDeviceOrProfileOwnerAdminLocked(userId);
- if (admin == null || admin.suspendedPackages == null) {
- return Collections.emptySet();
- } else {
- return new ArraySet<>(admin.suspendedPackages);
- }
- }
- }
-
/**
* We need to update the internal state of whether a user has completed setup or a
* device has paired once. After that, we ignore any changes that reset the
@@ -23523,7 +23818,39 @@
}
Slog.w(LOG_TAG, "Work apps may have been paused via suspension previously.");
- unsuspendAppsForQuietProfiles();
+ PackageManagerInternal pmi = mInjector.getPackageManagerInternal();
+ List<UserInfo> users = mUserManagerInternal.getUsers(true /* excludeDying */);
+
+ for (UserInfo user : users) {
+ if (!user.isManagedProfile() || !user.isQuietModeEnabled()) {
+ continue;
+ }
+ int userId = user.id;
+ Set<String> suspendedByAdmin;
+ synchronized (getLockObject()) {
+ ActiveAdmin admin = getDeviceOrProfileOwnerAdminLocked(userId);
+ // This is legacy code from Turn off Work 2.0 which is before setPackagesSuspended
+ // is migrated to PolicyEngine, so we only need to query the legacy ActiveAdmin here
+ if (admin == null || admin.suspendedPackages == null) {
+ suspendedByAdmin = Collections.emptySet();
+ } else {
+ suspendedByAdmin = new ArraySet<>(admin.suspendedPackages);
+ }
+ }
+ var packagesToUnsuspend = mInjector.getPackageManager(userId)
+ .getInstalledPackages(PackageManager.PackageInfoFlags.of(
+ MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE))
+ .stream()
+ .map(packageInfo -> packageInfo.packageName)
+ .filter(pkg -> !suspendedByAdmin.contains(pkg))
+ .toArray(String[]::new);
+
+ Slogf.i(LOG_TAG, "Unsuspending work apps for user %d", userId);
+ // When app suspension was used for quiet mode, the apps were suspended by platform
+ // package, just like when admin suspends them. So although it wasn't admin who
+ // suspended, this method will remove the right suspension record.
+ pmi.setPackagesSuspendedByAdmin(userId, packagesToUnsuspend, false /* suspended */);
+ }
}
public void setMtePolicy(int flags, String callerPackageName) {
@@ -23947,6 +24274,15 @@
@GuardedBy("getLockObject()")
private void migratePoliciesToPolicyEngineLocked() {
maybeMigrateSecurityLoggingPolicyLocked();
+ // ID format: <sdk-int>.<auto_increment_id>.<descriptions>'
+ String unmanagedBackupId = "35.1.unmanaged-mode";
+ boolean migrated = false;
+ migrated = migrated | maybeMigrateRequiredPasswordComplexityLocked(unmanagedBackupId);
+ migrated = migrated | maybeMigrateSuspendedPackagesLocked(unmanagedBackupId);
+ if (migrated) {
+ Slogf.i(LOG_TAG, "Backup made: " + unmanagedBackupId);
+ }
+ // Additional migration steps should repeat the pattern above with a new backupId.
}
private void migrateAutoTimezonePolicy() {
@@ -24211,6 +24547,23 @@
});
}
+ @GuardedBy("getLockObject()")
+ private void iterateThroughDpcAdminsLocked(BiConsumer<ActiveAdmin, EnforcingAdmin> runner) {
+ Binder.withCleanCallingIdentity(() -> {
+ List<UserInfo> users = mUserManager.getUsers();
+ for (UserInfo userInfo : users) {
+ ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id);
+ if (admin == null) continue;
+ EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+ admin.info.getComponent(),
+ userInfo.id,
+ admin);
+
+ runner.accept(admin, enforcingAdmin);
+ }
+ });
+ }
+
private List<PackageInfo> getInstalledPackagesOnUser(int userId) {
return mInjector.binderWithCleanCallingIdentity(() ->
mContext.getPackageManager().getInstalledPackagesAsUser(
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java b/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
index 7e8eaa7..2066376 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
@@ -19,9 +19,9 @@
import android.annotation.NonNull;
import android.app.admin.PolicyValue;
+import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
final class MostRestrictive<V> extends ResolutionMechanism<V> {
@@ -33,18 +33,21 @@
@Override
PolicyValue<V> resolve(@NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminPolicies) {
+ return resolve(new ArrayList<>(adminPolicies.values()));
+ }
+
+ @Override
+ PolicyValue<V> resolve(List<PolicyValue<V>> adminPolicies) {
if (adminPolicies.isEmpty()) {
return null;
}
for (PolicyValue<V> value : mMostToLeastRestrictive) {
- if (adminPolicies.containsValue(value)) {
+ if (adminPolicies.contains(value)) {
return value;
}
}
// Return first set policy if none can be found in known values
- Map.Entry<EnforcingAdmin, PolicyValue<V>> policy =
- adminPolicies.entrySet().stream().findFirst().get();
- return policy.getValue();
+ return adminPolicies.get(0);
}
@Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 7912cbc..3f9605a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -636,6 +636,33 @@
}
}
+ boolean isRequiredPasswordComplexityMigrated() {
+ synchronized (mData) {
+ return mData.mRequiredPasswordComplexityMigrated;
+ }
+ }
+
+ void markRequiredPasswordComplexityMigrated() {
+ synchronized (mData) {
+ mData.mRequiredPasswordComplexityMigrated = true;
+ mData.writeDeviceOwner();
+ }
+
+ }
+
+ boolean isSuspendedPackagesMigrated() {
+ synchronized (mData) {
+ return mData.mSuspendedPackagesMigrated;
+ }
+ }
+
+ void markSuspendedPackagesMigrated() {
+ synchronized (mData) {
+ mData.mSuspendedPackagesMigrated = true;
+ mData.writeDeviceOwner();
+ }
+ }
+
boolean isMigratedPostUpdate() {
synchronized (mData) {
return mData.mPoliciesMigratedPostUpdate;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
index d02cfee..2ea5f16 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
@@ -88,7 +88,9 @@
private static final String ATTR_MIGRATED_TO_POLICY_ENGINE = "migratedToPolicyEngine";
private static final String ATTR_SECURITY_LOG_MIGRATED = "securityLogMigrated";
-
+ private static final String ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED =
+ "passwordComplexityMigrated";
+ private static final String ATTR_SUSPENDED_PACKAGES_MIGRATED = "suspendedPackagesMigrated";
private static final String ATTR_MIGRATED_POST_UPGRADE = "migratedPostUpgrade";
// Internal state for the device owner package.
@@ -118,6 +120,8 @@
boolean mMigratedToPolicyEngine = false;
boolean mSecurityLoggingMigrated = false;
+ boolean mRequiredPasswordComplexityMigrated = false;
+ boolean mSuspendedPackagesMigrated = false;
boolean mPoliciesMigratedPostUpdate = false;
@@ -409,6 +413,14 @@
if (Flags.securityLogV2Enabled()) {
out.attributeBoolean(null, ATTR_SECURITY_LOG_MIGRATED, mSecurityLoggingMigrated);
}
+ if (Flags.unmanagedModeMigration()) {
+ out.attributeBoolean(null, ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED,
+ mRequiredPasswordComplexityMigrated);
+ out.attributeBoolean(null, ATTR_SUSPENDED_PACKAGES_MIGRATED,
+ mSuspendedPackagesMigrated);
+
+ }
+
out.endTag(null, TAG_POLICY_ENGINE_MIGRATION);
}
@@ -473,6 +485,12 @@
null, ATTR_MIGRATED_POST_UPGRADE, false);
mSecurityLoggingMigrated = Flags.securityLogV2Enabled()
&& parser.getAttributeBoolean(null, ATTR_SECURITY_LOG_MIGRATED, false);
+ mRequiredPasswordComplexityMigrated = Flags.unmanagedModeMigration()
+ && parser.getAttributeBoolean(null,
+ ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED, false);
+ mSuspendedPackagesMigrated = Flags.unmanagedModeMigration()
+ && parser.getAttributeBoolean(null,
+ ATTR_SUSPENDED_PACKAGES_MIGRATED, false);
break;
default:
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PackageSuspender.java b/services/devicepolicy/java/com/android/server/devicepolicy/PackageSuspender.java
new file mode 100644
index 0000000..40cf0e9
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PackageSuspender.java
@@ -0,0 +1,155 @@
+/*
+ * 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.devicepolicy;
+
+import static com.android.server.devicepolicy.DevicePolicyManagerService.LOG_TAG;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageManagerInternal;
+import android.util.ArraySet;
+
+import com.android.server.utils.Slogf;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Helper class for calling into PackageManagerInternal.setPackagesSuspendedByAdmin.
+ * Two main things this class encapsulates:
+ * 1. Handling of the DPM internal suspension exemption list
+ * 2. Calculating the failed packages result in the context of coexistence
+ *
+ * 1 is handled by the two internal methods {@link #suspendWithExemption(Set)} and
+ * {@link #unsuspendWithExemption(Set)} where the exemption list is taken into consideration
+ * before and after calling {@link PackageManagerInternal#setPackagesSuspendedByAdmin}.
+ * In order to compute 2, the resolved package suspension state before and after suspension is
+ * needed as multiple admins can both suspend the same packages under coexistence.
+ */
+public class PackageSuspender {
+
+ private final Set<String> mSuspendedPackageBefore;
+ private final Set<String> mSuspendedPackageAfter;
+ private final List<String> mExemptedPackages;
+ private final PackageManagerInternal mPackageManager;
+ private final int mUserId;
+
+ public PackageSuspender(@Nullable Set<String> suspendedPackageBefore,
+ @Nullable Set<String> suspendedPackageAfter, List<String> exemptedPackages,
+ PackageManagerInternal pmi, int userId) {
+ mSuspendedPackageBefore =
+ suspendedPackageBefore != null ? suspendedPackageBefore : Collections.emptySet();
+ mSuspendedPackageAfter =
+ suspendedPackageAfter != null ? suspendedPackageAfter : Collections.emptySet();
+ mExemptedPackages = exemptedPackages;
+ mPackageManager = pmi;
+ mUserId = userId;
+ }
+
+ /**
+ * Suspend packages that are requested by a single admin
+ *
+ * @return a list of packages that the admin has requested to suspend but could not be
+ * suspended, due to DPM and PackageManager exemption list.
+ *
+ */
+ public String[] suspend(Set<String> packages) {
+ // When suspending, call PM with the list of packages admin has requested, even if some
+ // of these packages are already in suspension (some other admin might have already
+ // suspended them). We do it this way so that we can simply return the failed list from
+ // PackageManager to the caller as the accurate list of unsuspended packages.
+ // This is different from the unsuspend() logic, please see below.
+ //
+ // For example admin A already suspended package 1, 2 and 3, but package 3 is
+ // PackageManager-exempted. Now admin B wants to suspend package 2, 3 and 4 (2 and 4 are
+ // suspendable). We need to return package 3 as the unsuspended package here, and we ask
+ // PackageManager to suspend package 2, 3 and 4 here (who will return package 3 in the
+ // failed list, and package 2 is already suspended).
+ Set<String> result = suspendWithExemption(packages);
+ return result.toArray(String[]::new);
+ }
+
+ /**
+ * Suspend packages considering the exemption list.
+ *
+ * @return the list of packages that couldn't be suspended, either due to the exemption list,
+ * or due to failures from PackageManagerInternal itself.
+ */
+ private Set<String> suspendWithExemption(Set<String> packages) {
+ Set<String> packagesToSuspend = new ArraySet<>(packages);
+ // Any original packages that are also in the exempted list will not be suspended and hence
+ // will appear in the final result.
+ Set<String> result = new ArraySet<>(mExemptedPackages);
+ result.retainAll(packagesToSuspend);
+ // Remove exempted packages before calling PackageManager
+ packagesToSuspend.removeAll(mExemptedPackages);
+ String[] failedPackages = mPackageManager.setPackagesSuspendedByAdmin(
+ mUserId, packagesToSuspend.toArray(String[]::new), true);
+ if (failedPackages == null) {
+ Slogf.w(LOG_TAG, "PM failed to suspend packages (%s)", packages);
+ return packages;
+ } else {
+ result.addAll(Arrays.asList(failedPackages));
+ return result;
+ }
+ }
+
+ /**
+ * Unsuspend packages that are requested by a single admin
+ *
+ * @return a list of packages that the admin has requested to unsuspend but could not be
+ * unsuspended, due to other amdin's policy or PackageManager restriction.
+ *
+ */
+ public String[] unsuspend(Set<String> packages) {
+ // Unlike suspend(), when unsuspending, call PackageManager with the delta of resolved
+ // suspended packages list and not what the admin has requested. This is because some
+ // packages might still be subject to another admin's suspension request.
+ Set<String> packagesToUnsuspend = new ArraySet<>(mSuspendedPackageBefore);
+ packagesToUnsuspend.removeAll(mSuspendedPackageAfter);
+
+ // To calculate the result (which packages are not unsuspended), start with packages that
+ // are still subject to another admin's suspension policy. This is calculated by
+ // intersecting the packages argument with mSuspendedPackageAfter.
+ Set<String> result = new ArraySet<>(packages);
+ result.retainAll(mSuspendedPackageAfter);
+ // Remove mExemptedPackages since they can't be suspended to start with.
+ result.removeAll(mExemptedPackages);
+ // Finally make the unsuspend() request and add packages that PackageManager can't unsuspend
+ // to the result.
+ result.addAll(unsuspendWithExemption(packagesToUnsuspend));
+ return result.toArray(String[]::new);
+ }
+
+ /**
+ * Unsuspend packages considering the exemption list.
+ *
+ * @return the list of packages that couldn't be unsuspended, either due to the exemption list,
+ * or due to failures from PackageManagerInternal itself.
+ */
+ private Set<String> unsuspendWithExemption(Set<String> packages) {
+ // when unsuspending, no need to consider exemption list since by definition they can't
+ // be suspended to begin with.
+ String[] failedPackages = mPackageManager.setPackagesSuspendedByAdmin(
+ mUserId, packages.toArray(String[]::new), false);
+ if (failedPackages == null) {
+ Slogf.w(LOG_TAG, "PM failed to unsuspend packages (%s)", packages);
+ }
+ return new ArraySet<>(failedPackages);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index 8bec384..a0ea4e9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -240,7 +240,7 @@
POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_INHERITABLE
| POLICY_FLAG_NON_COEXISTABLE_POLICY
| POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED,
- PolicyEnforcerCallbacks::setApplicationRestrictions,
+ PolicyEnforcerCallbacks::noOp,
new BundlePolicySerializer());
/**
@@ -263,7 +263,7 @@
new MostRecent<>(),
POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_NON_COEXISTABLE_POLICY,
// DevicePolicyManagerService handles the enforcement, this just takes care of storage
- (Long value, Context context, Integer userId, PolicyKey policyKey) -> true,
+ PolicyEnforcerCallbacks::noOp,
new LongPolicySerializer());
static PolicyDefinition<Integer> KEYGUARD_DISABLED_FEATURES = new PolicyDefinition<>(
@@ -271,7 +271,7 @@
new FlagUnion(),
POLICY_FLAG_LOCAL_ONLY_POLICY,
// Nothing is enforced for keyguard features, we just need to store it
- (Integer value, Context context, Integer userId, PolicyKey policyKey) -> true,
+ PolicyEnforcerCallbacks::noOp,
new IntegerPolicySerializer());
// This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
@@ -312,7 +312,7 @@
TRUE_MORE_RESTRICTIVE,
POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_INHERITABLE,
// Nothing is enforced, we just need to store it
- (Boolean value, Context context, Integer userId, PolicyKey policyKey) -> true,
+ PolicyEnforcerCallbacks::noOp,
new BooleanPolicySerializer());
/**
@@ -332,7 +332,7 @@
new NoArgsPolicyKey(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY),
new MostRecent<>(),
POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_INHERITABLE,
- (Set<String> value, Context context, Integer userId, PolicyKey policyKey) -> true,
+ PolicyEnforcerCallbacks::noOp,
new PackageSetPolicySerializer());
@@ -366,6 +366,30 @@
PolicyEnforcerCallbacks::setContentProtectionPolicy,
new IntegerPolicySerializer());
+ static PolicyDefinition<Integer> PASSWORD_COMPLEXITY = new PolicyDefinition<>(
+ new NoArgsPolicyKey(DevicePolicyIdentifiers.PASSWORD_COMPLEXITY_POLICY),
+ new MostRestrictive<>(
+ List.of(
+ new IntegerPolicyValue(
+ DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH),
+ new IntegerPolicyValue(
+ DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM),
+ new IntegerPolicyValue(
+ DevicePolicyManager.PASSWORD_COMPLEXITY_LOW),
+ new IntegerPolicyValue(
+ DevicePolicyManager.PASSWORD_COMPLEXITY_NONE))),
+ POLICY_FLAG_LOCAL_ONLY_POLICY,
+ PolicyEnforcerCallbacks::noOp,
+ new IntegerPolicySerializer());
+
+ static PolicyDefinition<Set<String>> PACKAGES_SUSPENDED =
+ new PolicyDefinition<>(
+ new NoArgsPolicyKey(
+ DevicePolicyIdentifiers.PACKAGES_SUSPENDED_POLICY),
+ new PackageSetUnion(),
+ PolicyEnforcerCallbacks::noOp,
+ new PackageSetPolicySerializer());
+
private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();
@@ -405,6 +429,13 @@
USB_DATA_SIGNALING);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.CONTENT_PROTECTION_POLICY,
CONTENT_PROTECTION);
+ // Intentionally not flagged since if the flag is flipped off on a device already
+ // having PASSWORD_COMPLEXITY policy in the on-device XML, it will cause the
+ // deserialization logic to break due to seeing an unknown tag.
+ POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PASSWORD_COMPLEXITY_POLICY,
+ PASSWORD_COMPLEXITY);
+ POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PACKAGES_SUSPENDED_POLICY,
+ PACKAGES_SUSPENDED);
// User Restriction Policies
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);
@@ -523,7 +554,7 @@
private final PolicyKey mPolicyKey;
private final ResolutionMechanism<V> mResolutionMechanism;
private final int mPolicyFlags;
- // A function that accepts policy to apple, context, userId, callback arguments, and returns
+ // A function that accepts policy to apply, context, userId, callback arguments, and returns
// true if the policy has been enforced successfully.
private final QuadFunction<V, Context, Integer, PolicyKey, Boolean> mPolicyEnforcerCallback;
private final PolicySerializer<V> mPolicySerializer;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
index 04d277e..e1cb37d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -73,6 +73,10 @@
private static final String LOG_TAG = "PolicyEnforcerCallbacks";
+ static <T> boolean noOp(T value, Context context, Integer userId, PolicyKey policyKey) {
+ return true;
+ }
+
static boolean setAutoTimezoneEnabled(@Nullable Boolean enabled, @NonNull Context context) {
if (!DevicePolicyManagerService.isUnicornFlagEnabled()) {
Slogf.w(LOG_TAG, "Trying to enforce setAutoTimezoneEnabled while flag is off.");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
index c544ebc..245c438 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
@@ -200,7 +200,7 @@
pw.println(mPolicyDefinition.getPolicyKey());
pw.increaseIndent();
- pw.println("Per-admin Policy");
+ pw.println("Per-admin Policy:");
pw.increaseIndent();
if (mPoliciesSetByAdmins.size() == 0) {
pw.println("null");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java b/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
index c321aa1..ad7ac2b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
@@ -20,9 +20,24 @@
import android.app.admin.PolicyValue;
import java.util.LinkedHashMap;
+import java.util.List;
abstract class ResolutionMechanism<V> {
+ /**
+ * The most generic resolution logic where we know both the policy value and the admin who
+ * sets it.
+ */
@Nullable
abstract PolicyValue<V> resolve(LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminPolicies);
+
+ /**
+ * A special resolution logic that does not care about admins who set them. Only applicable to
+ * a subset of ResolutionMechanism.
+ */
+ @Nullable
+ PolicyValue<V> resolve(List<PolicyValue<V>> adminPolicies) {
+ throw new UnsupportedOperationException();
+ }
+
abstract android.app.admin.ResolutionMechanism<V> getParcelableResolutionMechanism();
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index cfe4e17..927df8b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -761,6 +761,9 @@
}
}
+ private static final long BINDER_CALLBACK_THROTTLE_MS = 10_100L;
+ private long mBinderCallbackLast = -1;
+
private void run() {
TimingsTraceAndSlog t = new TimingsTraceAndSlog();
try {
@@ -965,6 +968,14 @@
Binder.setTransactionCallback(new IBinderCallback() {
@Override
public void onTransactionError(int pid, int code, int flags, int err) {
+
+ final long now = SystemClock.uptimeMillis();
+ if (now < mBinderCallbackLast + BINDER_CALLBACK_THROTTLE_MS) {
+ Slog.d(TAG, "Too many transaction errors, throttling freezer binder callback.");
+ return;
+ }
+ mBinderCallbackLast = now;
+ Slog.wtfStack(TAG, "Binder Transaction Error");
mActivityManagerService.frozenBinderTransactionDetected(pid, code, flags, err);
}
});
diff --git a/services/robotests/Android.bp b/services/robotests/Android.bp
index a70802a..6c4158e 100644
--- a/services/robotests/Android.bp
+++ b/services/robotests/Android.bp
@@ -64,6 +64,8 @@
instrumentation_for: "FrameworksServicesLib",
upstream: true,
+
+ strict_mode: false,
}
filegroup {
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
index 569786b..3ace3fb 100644
--- a/services/robotests/backup/Android.bp
+++ b/services/robotests/backup/Android.bp
@@ -68,4 +68,6 @@
upstream: true,
+ strict_mode: false,
+
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 3628a57..d3efcb6 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -16,7 +16,6 @@
package com.android.server.display;
-import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
@@ -44,6 +43,7 @@
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.Handler;
import android.os.PowerManager;
+import android.os.SystemClock;
import android.os.test.TestLooper;
import android.util.SparseArray;
import android.view.Display;
@@ -54,6 +54,7 @@
import com.android.server.display.brightness.clamper.BrightnessClamperController;
import com.android.server.display.config.HysteresisLevels;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.testutils.OffsettableClock;
import org.junit.After;
@@ -68,6 +69,8 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class AutomaticBrightnessControllerTest {
+ private static final int ANDROID_SLEEP_TIME = 1000;
+ private static final int NANO_SECONDS_MULTIPLIER = 1000000;
private static final float BRIGHTNESS_MIN_FLOAT = 0.0f;
private static final float BRIGHTNESS_MAX_FLOAT = 1.0f;
private static final int LIGHT_SENSOR_RATE = 20;
@@ -100,6 +103,8 @@
@Mock BrightnessRangeController mBrightnessRangeController;
@Mock
BrightnessClamperController mBrightnessClamperController;
+ @Mock
+ DisplayManagerFlags mDisplayManagerFlags;
@Mock BrightnessThrottler mBrightnessThrottler;
@Before
@@ -148,8 +153,18 @@
}
@Override
- AutomaticBrightnessController.Clock createClock() {
- return mClock::now;
+ AutomaticBrightnessController.Clock createClock(boolean isEnabled) {
+ return new AutomaticBrightnessController.Clock() {
+ @Override
+ public long uptimeMillis() {
+ return mClock.now();
+ }
+
+ @Override
+ public long getSensorEventScaleTime() {
+ return mClock.now() + ANDROID_SLEEP_TIME;
+ }
+ };
}
}, // pass in test looper instead, pass in offsettable clock
@@ -166,7 +181,7 @@
mContext, mBrightnessRangeController, mBrightnessThrottler,
useHorizon ? AMBIENT_LIGHT_HORIZON_SHORT : 1,
useHorizon ? AMBIENT_LIGHT_HORIZON_LONG : 10000, userLux, userNits,
- mBrightnessClamperController
+ mBrightnessClamperController, mDisplayManagerFlags
);
when(mBrightnessRangeController.getCurrentBrightnessMax()).thenReturn(
@@ -350,7 +365,7 @@
when(mBrightnessMappingStrategy.getShortTermModelTimeout()).thenReturn(2000L);
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
when(mBrightnessMappingStrategy.shouldResetShortTermModel(
123f, 0.5f)).thenReturn(true);
@@ -360,7 +375,7 @@
mBrightnessMappingStrategy.getShortTermModelTimeout() + 1000);
mTestLooper.dispatchAll();
- mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT, /* sendUpdate= */ true);
mTestLooper.moveTimeForward(4000);
mTestLooper.dispatchAll();
@@ -394,14 +409,14 @@
when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(0.51f);
when(mBrightnessMappingStrategy.getUserLux()).thenReturn(123.0f);
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
// Time does not move forward, since clock is doesn't increment naturally.
mTestLooper.dispatchAll();
// Sensor reads 100000 lux,
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 678910));
- mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT, /* sendUpdate= */ true);
// Verify short term model is not reset.
verify(mBrightnessMappingStrategy, never()).clearUserDataPoints();
@@ -432,7 +447,7 @@
when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(0.5f);
when(mBrightnessMappingStrategy.getUserLux()).thenReturn(123f);
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn(
PowerManager.BRIGHTNESS_INVALID_FLOAT);
when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn(
@@ -446,7 +461,7 @@
mBrightnessMappingStrategy.getShortTermModelTimeout() + 1000);
mTestLooper.dispatchAll();
- mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT, /* sendUpdate= */ true);
mTestLooper.moveTimeForward(4000);
mTestLooper.dispatchAll();
@@ -479,7 +494,7 @@
when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(0.5f);
when(mBrightnessMappingStrategy.getUserLux()).thenReturn(123f);
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn(
PowerManager.BRIGHTNESS_INVALID_FLOAT);
when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn(
@@ -493,7 +508,7 @@
// Do not fast-forward time.
mTestLooper.dispatchAll();
- mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT, /* sendUpdate= */ true);
// Do not fast-forward time
mTestLooper.dispatchAll();
@@ -523,7 +538,7 @@
// No user brightness interaction.
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn(
PowerManager.BRIGHTNESS_INVALID_FLOAT);
when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn(
@@ -534,7 +549,7 @@
// Do not fast-forward time.
mTestLooper.dispatchAll();
- mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT, /* sendUpdate= */ true);
// Do not fast-forward time
mTestLooper.dispatchAll();
@@ -568,7 +583,7 @@
verify(mBrightnessMappingStrategy, times(3)).getBrightness(anyFloat(), any(), anyInt());
// Now let's do the same for idle mode
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
// Called once when switching,
// setAmbientLux() is called twice and once in updateAutoBrightness(),
// nextAmbientLightBrighteningTransition() and nextAmbientLightDarkeningTransition() are
@@ -800,6 +815,43 @@
}
@Test
+ public void testAmbientLuxBuffers_prunedBeyondLongHorizonExceptLatestValue() throws Exception {
+ when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(true);
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+ verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
+ eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
+ SensorEventListener listener = listenerCaptor.getValue();
+
+ // Choose values such that the ring buffer's capacity is extended and the buffer is pruned
+ int increment = 11;
+ int lux = 5000;
+ for (int i = 0; i < 1000; i++) {
+ lux += increment;
+ mClock.fastForward(increment);
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, lux,
+ (mClock.now() + ANDROID_SLEEP_TIME) * NANO_SECONDS_MULTIPLIER));
+ }
+ mClock.fastForward(AMBIENT_LIGHT_HORIZON_LONG + 10);
+ int newLux = 2000;
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, newLux,
+ (mClock.now() + ANDROID_SLEEP_TIME) * NANO_SECONDS_MULTIPLIER));
+
+ float[] sensorValues = mController.getLastSensorValues();
+ long[] sensorTimestamps = mController.getLastSensorTimestamps();
+ // Only the values within the horizon should be kept
+ assertEquals(2, sensorValues.length);
+ assertEquals(2, sensorTimestamps.length);
+
+ assertEquals(lux, sensorValues[0], EPSILON);
+ assertEquals(newLux, sensorValues[1], EPSILON);
+ assertEquals(mClock.now() + ANDROID_SLEEP_TIME - AMBIENT_LIGHT_HORIZON_LONG,
+ sensorTimestamps[0]);
+ assertEquals(mClock.now() + ANDROID_SLEEP_TIME,
+ sensorTimestamps[1]);
+ }
+
+ @Test
public void testGetSensorReadingsFullBuffer() throws Exception {
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
@@ -966,7 +1018,7 @@
BrightnessMappingStrategy.INVALID_NITS, /* applyDebounce= */ true,
/* useHorizon= */ false);
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
@@ -1003,7 +1055,7 @@
BrightnessMappingStrategy.INVALID_NITS, /* applyDebounce= */ true,
/* useHorizon= */ false);
- mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE, /* sendUpdate= */ true);
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
@@ -1030,35 +1082,6 @@
}
@Test
- public void testBrightnessBasedOnLastUsedLux() throws Exception {
- ArgumentCaptor<SensorEventListener> listenerCaptor =
- ArgumentCaptor.forClass(SensorEventListener.class);
- verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
- eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
- SensorEventListener listener = listenerCaptor.getValue();
-
- // Set up system to return 0.3f as a brightness value
- float lux = 100.0f;
- // Brightness as float (from 0.0f to 1.0f)
- float normalizedBrightness = 0.3f;
- when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux)).thenReturn(lux);
- when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux)).thenReturn(lux);
- when(mBrightnessMappingStrategy.getBrightness(eq(lux), /* packageName= */ eq(null),
- /* category= */ anyInt())).thenReturn(normalizedBrightness);
- when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
-
- // Send a new sensor value, disable the sensor and verify
- listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux));
- mController.configure(AUTO_BRIGHTNESS_DISABLED, /* configuration= */ null,
- /* brightness= */ 0, /* userChangedBrightness= */ false, /* adjustment= */ 0,
- /* userChanged= */ false, DisplayPowerRequest.POLICY_BRIGHT, Display.STATE_ON,
- /* shouldResetShortTermModel= */ true);
- assertEquals(normalizedBrightness,
- mController.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- /* brightnessEvent= */ null), EPSILON);
- }
-
- @Test
public void testAutoBrightnessInDoze() throws Exception {
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
@@ -1089,9 +1112,6 @@
assertEquals(normalizedBrightness * DOZE_SCALE_FACTOR,
mController.getAutomaticScreenBrightness(
/* brightnessEvent= */ null), EPSILON);
- assertEquals(normalizedBrightness * DOZE_SCALE_FACTOR,
- mController.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- /* brightnessEvent= */ null), EPSILON);
}
@Test
@@ -1113,7 +1133,7 @@
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
// Switch mode to DOZE
- mController.switchMode(AUTO_BRIGHTNESS_MODE_DOZE);
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DOZE, /* sendUpdate= */ false);
// Set policy to DOZE
mController.configure(AUTO_BRIGHTNESS_ENABLED, /* configuration= */ null,
@@ -1127,9 +1147,6 @@
// The brightness should not be scaled by the doze factor
assertEquals(normalizedBrightness,
mController.getAutomaticScreenBrightness(/* brightnessEvent= */ null), EPSILON);
- assertEquals(normalizedBrightness,
- mController.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- /* brightnessEvent= */ null), EPSILON);
}
@Test
@@ -1162,8 +1179,63 @@
// The brightness should not be scaled by the doze factor
assertEquals(normalizedBrightness,
mController.getAutomaticScreenBrightness(/* brightnessEvent= */ null), EPSILON);
+ }
+
+ @Test
+ public void testSwitchMode_UpdateBrightnessImmediately() throws Exception {
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+ verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
+ eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
+ SensorEventListener listener = listenerCaptor.getValue();
+
+ // Set up system to return 0.3f as a brightness value
+ float lux = 100.0f;
+ // Brightness as float (from 0.0f to 1.0f)
+ float normalizedBrightness = 0.3f;
+ when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux)).thenReturn(lux);
+ when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux)).thenReturn(lux);
+ when(mDozeBrightnessMappingStrategy.getBrightness(eq(lux), /* packageName= */ eq(null),
+ /* category= */ anyInt())).thenReturn(normalizedBrightness);
+ when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
+
+ // Send a new sensor value
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux));
+
+ // Switch mode to DOZE
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DOZE, /* sendUpdate= */ false);
+
assertEquals(normalizedBrightness,
- mController.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- /* brightnessEvent= */ null), EPSILON);
+ mController.getAutomaticScreenBrightness(/* brightnessEvent= */ null), EPSILON);
+ }
+
+ @Test
+ public void testSwitchMode_UpdateBrightnessInBackground() throws Exception {
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+ verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
+ eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
+ SensorEventListener listener = listenerCaptor.getValue();
+
+ // Set up system to return 0.3f as a brightness value
+ float lux = 100.0f;
+ // Brightness as float (from 0.0f to 1.0f)
+ float normalizedBrightness = 0.3f;
+ when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux)).thenReturn(lux);
+ when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux)).thenReturn(lux);
+ when(mDozeBrightnessMappingStrategy.getBrightness(eq(lux), /* packageName= */ eq(null),
+ /* category= */ anyInt())).thenReturn(normalizedBrightness);
+ when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
+
+ // Send a new sensor value
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux));
+
+ // Switch mode to DOZE
+ mController.switchMode(AUTO_BRIGHTNESS_MODE_DOZE, /* sendUpdate= */ true);
+ mClock.fastForward(SystemClock.uptimeMillis());
+ mTestLooper.dispatchAll();
+
+ assertEquals(normalizedBrightness,
+ mController.getAutomaticScreenBrightness(/* brightnessEvent= */ null), EPSILON);
}
}
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 e5685c7..98f572d 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -1021,6 +1021,36 @@
}
@Test
+ public void testAutoBrightnessEnabled_DisplayIsInDoze_OffloadAllows() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true);
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+ when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.offloadControlsDozeAutoBrightness()).thenReturn(true);
+ when(mDisplayOffloadSession.allowAutoBrightnessInDoze()).thenReturn(true);
+ mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.automaticBrightnessController).configure(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
+ /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ /* userChangedBrightness= */ false, /* adjustment= */ 0,
+ /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_DOZE,
+ Display.STATE_DOZE, /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController)
+ .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
+ }
+
+ @Test
public void testAutoBrightnessDisabled_ManualBrightnessMode() {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
@@ -1067,7 +1097,7 @@
}
@Test
- public void testAutoBrightnessDisabled_DisplayIsInDoze() {
+ public void testAutoBrightnessDisabled_DisplayIsInDoze_ConfigDoesNotAllow() {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
@@ -1093,6 +1123,36 @@
}
@Test
+ public void testAutoBrightnessDisabled_DisplayIsInDoze_OffloadDoesNotAllow() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true);
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+ when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.offloadControlsDozeAutoBrightness()).thenReturn(true);
+ when(mDisplayOffloadSession.allowAutoBrightnessInDoze()).thenReturn(false);
+ mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.automaticBrightnessController).configure(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+ /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ /* userChangedBrightness= */ false, /* adjustment= */ 0,
+ /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_DOZE,
+ Display.STATE_DOZE, /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController).setAutoBrightnessEnabled(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE);
+ }
+
+ @Test
public void testAutoBrightnessDisabled_FollowerDisplay() {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
@@ -1191,7 +1251,8 @@
/* ambientLightHorizonLong= */ anyInt(),
eq(lux),
eq(nits),
- any(BrightnessClamperController.class)
+ any(BrightnessClamperController.class),
+ any(DisplayManagerFlags.class)
);
}
@@ -1668,7 +1729,8 @@
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
- verify(mHolder.automaticBrightnessController).switchMode(AUTO_BRIGHTNESS_MODE_DOZE);
+ verify(mHolder.automaticBrightnessController)
+ .switchMode(AUTO_BRIGHTNESS_MODE_DOZE, /* sendUpdate= */ false);
// Back to default mode
when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
@@ -1676,7 +1738,8 @@
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
- verify(mHolder.automaticBrightnessController).switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT);
+ verify(mHolder.automaticBrightnessController)
+ .switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT, /* sendUpdate= */ false);
}
@Test
@@ -1690,7 +1753,7 @@
advanceTime(1); // Run updatePowerState
verify(mHolder.automaticBrightnessController, never())
- .switchMode(AUTO_BRIGHTNESS_MODE_DOZE);
+ .switchMode(eq(AUTO_BRIGHTNESS_MODE_DOZE), /* sendUpdate= */ anyBoolean());
}
@Test
@@ -1703,7 +1766,7 @@
advanceTime(1); // Run updatePowerState
verify(mHolder.automaticBrightnessController, never())
- .switchMode(AUTO_BRIGHTNESS_MODE_DOZE);
+ .switchMode(eq(AUTO_BRIGHTNESS_MODE_DOZE), /* sendUpdate= */ anyBoolean());
}
@Test
@@ -1764,37 +1827,7 @@
}
@Test
- public void testInitialDozeBrightness_AutoBrightnessEnabled() {
- when(mDisplayManagerFlagsMock.areAutoBrightnessModesEnabled()).thenReturn(true);
- when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
- mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
- float brightness = 0.277f;
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(mHolder.automaticBrightnessController
- .getAutomaticScreenBrightnessBasedOnLastUsedLux(any(BrightnessEvent.class)))
- .thenReturn(brightness);
- when(mHolder.hbmController.getCurrentBrightnessMax())
- .thenReturn(PowerManager.BRIGHTNESS_MAX);
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_DOZE;
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.animator).animateTo(eq(brightness),
- /* linearSecondTarget= */ anyFloat(), /* rate= */ anyFloat(),
- /* ignoreAnimationLimits= */ anyBoolean());
- verify(mHolder.brightnessSetting).setBrightness(brightness);
- }
-
- @Test
- public void testInitialDozeBrightness_AutoBrightnessDisabled() {
+ public void testDozeManualBrightness() {
when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
Settings.System.putInt(mContext.getContentResolver(),
@@ -1827,22 +1860,17 @@
}
@Test
- public void testInitialDozeBrightness_AbcIsNull() {
- when(mDisplayManagerFlagsMock.areAutoBrightnessModesEnabled()).thenReturn(true);
+ public void testDozeManualBrightness_AbcIsNull() {
when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true,
/* isAutoBrightnessAvailable= */ false);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
float brightness = 0.277f;
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(mHolder.automaticBrightnessController
- .getAutomaticScreenBrightnessBasedOnLastUsedLux(any(BrightnessEvent.class)))
- .thenReturn(brightness);
+ when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
when(mHolder.hbmController.getCurrentBrightnessMax())
.thenReturn(PowerManager.BRIGHTNESS_MAX);
when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
@@ -1850,13 +1878,20 @@
DisplayPowerRequest dpr = new DisplayPowerRequest();
dpr.policy = DisplayPowerRequest.POLICY_DOZE;
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
+ advanceTime(1); // Run updatePowerState, initialize
- // Automatic Brightness Controller is null so no initial doze brightness should be set and
- // we should not crash
- verify(mHolder.animator, never()).animateTo(eq(brightness),
+ ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+ ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+ verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+ BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+ listener.onBrightnessChanged(brightness);
+ advanceTime(1); // Send messages, run updatePowerState
+
+ verify(mHolder.animator).animateTo(eq(brightness * DOZE_SCALE_FACTOR),
/* linearSecondTarget= */ anyFloat(), /* rate= */ anyFloat(),
/* ignoreAnimationLimits= */ anyBoolean());
+ assertEquals(brightness * DOZE_SCALE_FACTOR, mHolder.dpc.getDozeBrightnessForOffload(),
+ /* delta= */ 0);
}
@Test
@@ -1864,6 +1899,8 @@
float brightness = 0.121f;
when(mPowerManagerMock.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)).thenReturn(brightness);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
@@ -1881,6 +1918,31 @@
eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
}
+ @Test
+ public void testDefaultDozeBrightness_ShouldNotBeUsedIfAutoBrightnessAllowedInDoze() {
+ float brightness = 0.121f;
+ when(mPowerManagerMock.getBrightnessConstraint(
+ PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)).thenReturn(brightness);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true);
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+ when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ when(mHolder.hbmController.getCurrentBrightnessMax())
+ .thenReturn(PowerManager.BRIGHTNESS_MAX);
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.animator, never()).animateTo(eq(brightness),
+ /* linearSecondTarget= */ anyFloat(), /* rate= */ anyFloat(),
+ /* ignoreAnimationLimits= */ anyBoolean());
+ }
+
/**
* Creates a mock and registers it to {@link LocalServices}.
*/
@@ -2186,7 +2248,8 @@
BrightnessRangeController brightnessRangeController,
BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userNits,
- BrightnessClamperController brightnessClamperController) {
+ BrightnessClamperController brightnessClamperController,
+ DisplayManagerFlags displayManagerFlags) {
return mAutomaticBrightnessController;
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 7fd96c5..12050e1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -1246,6 +1246,11 @@
@Override
public void onBlockingScreenOn(Runnable unblocker) {}
+
+ @Override
+ public boolean allowAutoBrightnessInDoze() {
+ return true;
+ }
});
mDisplayOffloadSession = new DisplayOffloadSessionImpl(mDisplayOffloader,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/TestUtils.java b/services/tests/displayservicetests/src/com/android/server/display/TestUtils.java
index 8b45145..18dfcc1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/TestUtils.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/TestUtils.java
@@ -30,13 +30,21 @@
public final class TestUtils {
public static SensorEvent createSensorEvent(Sensor sensor, int value) throws Exception {
+ return createSensorEvent(sensor, value, SystemClock.elapsedRealtimeNanos());
+ }
+
+ /**
+ * Creates a light sensor event
+ */
+ public static SensorEvent createSensorEvent(Sensor sensor, int value, long timestamp)
+ throws Exception {
final Constructor<SensorEvent> constructor =
SensorEvent.class.getDeclaredConstructor(int.class);
constructor.setAccessible(true);
final SensorEvent event = constructor.newInstance(1);
event.sensor = sensor;
event.values[0] = value;
- event.timestamp = SystemClock.elapsedRealtimeNanos();
+ event.timestamp = timestamp;
return event;
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
index 09f5bb6..498bffd 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
@@ -343,17 +343,11 @@
AutomaticBrightnessController.class);
when(automaticBrightnessController.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
.thenReturn(automaticScreenBrightness);
- when(automaticBrightnessController.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- any(BrightnessEvent.class)))
- .thenReturn(automaticScreenBrightness);
mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
automaticBrightnessController);
assertEquals(automaticScreenBrightness,
mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
new BrightnessEvent(DISPLAY_ID)), 0.0f);
- assertEquals(automaticScreenBrightness,
- mAutomaticBrightnessStrategy.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- new BrightnessEvent(DISPLAY_ID)), 0.0f);
}
@Test
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index d19f479..afb5a5c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
@@ -273,7 +274,8 @@
mAutomaticBrightnessStrategy.setAutoBrightnessState(Display.STATE_ON,
allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
userSetBrightnessChanged);
- verify(mAutomaticBrightnessController, never()).switchMode(anyInt());
+ verify(mAutomaticBrightnessController, never())
+ .switchMode(anyInt(), /* sendUpdate= */ anyBoolean());
// Validate interaction when automaticBrightnessController is in non-idle mode, and display
// state is ON
@@ -282,7 +284,8 @@
allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
userSetBrightnessChanged);
verify(mAutomaticBrightnessController).switchMode(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT);
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT,
+ /* sendUpdate= */ false);
// Validate interaction when automaticBrightnessController is in non-idle mode, and display
// state is DOZE
@@ -290,7 +293,8 @@
allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
userSetBrightnessChanged);
verify(mAutomaticBrightnessController).switchMode(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE);
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE,
+ /* sendUpdate= */ false);
}
@Test
@@ -388,17 +392,11 @@
AutomaticBrightnessController.class);
when(automaticBrightnessController.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
.thenReturn(automaticScreenBrightness);
- when(automaticBrightnessController.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- any(BrightnessEvent.class)))
- .thenReturn(automaticScreenBrightness);
mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
automaticBrightnessController);
assertEquals(automaticScreenBrightness,
mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
new BrightnessEvent(DISPLAY_ID), false), 0.0f);
- assertEquals(automaticScreenBrightness,
- mAutomaticBrightnessStrategy.getAutomaticScreenBrightnessBasedOnLastUsedLux(
- new BrightnessEvent(DISPLAY_ID)), 0.0f);
}
@Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index 3399565..396f4da 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -25,6 +25,7 @@
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE;
import static com.google.common.truth.Truth.assertThat;
@@ -42,17 +43,23 @@
import android.content.pm.Signature;
import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
+import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
+import android.testing.TestableContext;
import androidx.test.InstrumentationRegistry;
+import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.mockingservicestests.R;
import com.android.server.backup.FileMetadata;
+import com.android.server.backup.Flags;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.restore.PerformAdbRestoreTask;
import com.android.server.backup.restore.RestorePolicy;
@@ -61,6 +68,7 @@
import com.google.common.hash.Hashing;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -86,6 +94,8 @@
@Mock private BytesReadListener mBytesReadListenerMock;
@Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
@Mock private PackageManagerInternal mMockPackageManagerInternal;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private final PackageManagerStub mPackageManagerStub = new PackageManagerStub();
private Context mContext;
@@ -95,7 +105,7 @@
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mContext = InstrumentationRegistry.getContext();
+ mContext = new TestableContext(ApplicationProvider.getApplicationContext());
mUserId = UserHandle.USER_SYSTEM;
}
@@ -515,6 +525,107 @@
@Test
public void
+ chooseRestorePolicy_flagOnNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsIgnore()
+ throws Exception {
+
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ENABLE_V_TO_U_RESTORE_FOR_SYSTEM_COMPONENTS_IN_ALLOWLIST);
+
+ TarBackupReader tarBackupReader = createTarBackupReader();
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "test");
+
+ Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+ FileMetadata info = new FileMetadata();
+ info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;
+
+ PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
+ PackageManagerStub.sPackageInfo = packageInfo;
+
+ doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+ packageInfo.packageName);
+ RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+ false /* allowApks */, info, signatures, mMockPackageManagerInternal,
+ mUserId, mContext);
+
+ assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+ assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+ LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE);
+ }
+
+
+ @Test
+ public void
+ chooseRestorePolicy_flagOffNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsAccept()
+ throws Exception {
+
+ mSetFlagsRule.disableFlags(
+ Flags.FLAG_ENABLE_V_TO_U_RESTORE_FOR_SYSTEM_COMPONENTS_IN_ALLOWLIST);
+
+ TarBackupReader tarBackupReader = createTarBackupReader();
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "test");
+
+ Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+ FileMetadata info = new FileMetadata();
+ info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;
+
+ PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
+ PackageManagerStub.sPackageInfo = packageInfo;
+
+ doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+ packageInfo.packageName);
+ RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+ false /* allowApks */, info, signatures, mMockPackageManagerInternal,
+ mUserId, mContext);
+
+ assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+ assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+ LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
+
+ }
+
+ @Test
+ public void
+ chooseRestorePolicy_flagOnNotRestoreAnyVersionVToURestoreAndNotInAllowlist_returnsIgnore()
+ throws Exception {
+
+ mSetFlagsRule.enableFlags(
+ Flags.FLAG_ENABLE_V_TO_U_RESTORE_FOR_SYSTEM_COMPONENTS_IN_ALLOWLIST);
+
+ TarBackupReader tarBackupReader = createTarBackupReader();
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "pkg");
+
+ Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+ FileMetadata info = new FileMetadata();
+ info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;
+
+ PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
+ PackageManagerStub.sPackageInfo = packageInfo;
+
+ doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+ packageInfo.packageName);
+ RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+ false /* allowApks */, info, signatures, mMockPackageManagerInternal,
+ mUserId, mContext);
+
+ assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+ assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+ LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
+ }
+
+ @Test
+ public void
chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchButAllowApksAndHasApk_returnsAcceptIfApk()
throws Exception {
InputStream inputStream = mContext.getResources().openRawResource(
@@ -523,6 +634,10 @@
inputStream, null);
TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "pkg");
+
Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
FileMetadata info = new FileMetadata();
info.version = 2;
@@ -564,6 +679,10 @@
inputStream, null);
TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "pkg");
+
Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
FileMetadata info = new FileMetadata();
info.version = 2;
@@ -596,5 +715,33 @@
assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
}
+
+ private TarBackupReader createTarBackupReader() throws Exception {
+ InputStream inputStream = mContext.getResources().openRawResource(
+ R.raw.backup_telephony_no_password);
+ InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+ inputStream, null);
+ TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+ mBytesReadListenerMock, mBackupManagerMonitorMock);
+ return tarBackupReader;
+ }
+
+ private PackageInfo createNonRestoreAnyVersionUPackage(){
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = "test";
+ packageInfo.applicationInfo = new ApplicationInfo();
+ packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+ packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+ packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+ packageInfo.applicationInfo.backupAgentName = null;
+ packageInfo.signingInfo = new SigningInfo(
+ new SigningDetails(
+ new Signature[]{FAKE_SIGNATURE_1},
+ SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null));
+ packageInfo.versionCode = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+ return packageInfo;
+ }
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BinaryStatePowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BinaryStatePowerStatsProcessorTest.java
new file mode 100644
index 0000000..be1c121
--- /dev/null
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BinaryStatePowerStatsProcessorTest.java
@@ -0,0 +1,283 @@
+/*
+ * 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.power.stats;
+
+import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND;
+import static android.os.BatteryConsumer.PROCESS_STATE_CACHED;
+import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND;
+import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE;
+
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.POWER_STATE_OTHER;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_ON;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_OTHER;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_POWER;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_PROCESS_STATE;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_SCREEN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+import android.os.PersistableBundle;
+import android.os.Process;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.os.MonotonicClock;
+import com.android.internal.os.PowerStats;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+public class BinaryStatePowerStatsProcessorTest {
+ @Rule(order = 0)
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
+ .setProvideMainThread(true)
+ .build();
+
+ private static final double PRECISION = 0.00001;
+ private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42;
+ private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101;
+ private static final int POWER_COMPONENT = BatteryConsumer.POWER_COMPONENT_AUDIO;
+ private static final int TEST_STATE_FLAG = 0x1;
+
+ private final MockClock mClock = new MockClock();
+ private final MonotonicClock mMonotonicClock = new MonotonicClock(0, mClock);
+ private final PowerStatsUidResolver mUidResolver = new PowerStatsUidResolver();
+
+ private static class TestBinaryStatePowerStatsProcessor extends BinaryStatePowerStatsProcessor {
+ TestBinaryStatePowerStatsProcessor(int powerComponentId,
+ double averagePowerMilliAmp, PowerStatsUidResolver uidResolver) {
+ super(powerComponentId, uidResolver, averagePowerMilliAmp);
+ }
+
+ @Override
+ protected int getBinaryState(BatteryStats.HistoryItem item) {
+ return (item.states & TEST_STATE_FLAG) != 0 ? STATE_ON : STATE_OFF;
+ }
+ }
+
+ @Test
+ public void powerProfileModel() {
+ TestBinaryStatePowerStatsProcessor processor = new TestBinaryStatePowerStatsProcessor(
+ POWER_COMPONENT, /* averagePowerMilliAmp */ 100, mUidResolver);
+
+ BinaryStatePowerStatsLayout statsLayout = new BinaryStatePowerStatsLayout();
+
+ PowerComponentAggregatedPowerStats stats = createAggregatedPowerStats(processor);
+
+ processor.noteStateChange(stats, buildHistoryItem(0, true, APP_UID1));
+
+ // Turn the screen off after 2.5 seconds
+ stats.setState(STATE_SCREEN, SCREEN_STATE_OTHER, 2500);
+ stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_BACKGROUND, 2500);
+ stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND_SERVICE, 5000);
+
+ processor.noteStateChange(stats, buildHistoryItem(6000, false, APP_UID1));
+
+ processor.noteStateChange(stats, buildHistoryItem(7000, true, APP_UID2));
+
+ processor.finish(stats, 11000);
+
+ // Total usage duration is 10000
+ // Total estimated power = 10000 * 100 = 1000000 mA-ms = 0.277777 mAh
+ // Screen-on - 25%
+ // Screen-off - 75%
+ double expectedPower = 0.277778;
+ long[] deviceStats = new long[stats.getPowerStatsDescriptor().statsArrayLength];
+ stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_ON));
+ assertThat(statsLayout.getDevicePowerEstimate(deviceStats))
+ .isWithin(PRECISION).of(expectedPower * 0.25);
+
+ stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_OTHER));
+ assertThat(statsLayout.getDevicePowerEstimate(deviceStats))
+ .isWithin(PRECISION).of(expectedPower * 0.75);
+
+ // UID1 =
+ // 6000 * 100 = 600000 mA-ms = 0.166666 mAh
+ // split between three different states
+ double expectedPower1 = 0.166666;
+ long[] uidStats = new long[stats.getPowerStatsDescriptor().uidStatsArrayLength];
+ stats.getUidStats(uidStats, APP_UID1,
+ states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_FOREGROUND));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000);
+
+ stats.getUidStats(uidStats, APP_UID1,
+ states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_BACKGROUND));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000);
+
+ stats.getUidStats(uidStats, APP_UID1,
+ states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_FOREGROUND_SERVICE));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower1 * 1000 / 6000);
+
+ // UID2 =
+ // 4000 * 100 = 400000 mA-ms = 0.111111 mAh
+ // all in the same state
+ double expectedPower2 = 0.111111;
+ stats.getUidStats(uidStats, APP_UID2,
+ states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_CACHED));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower2);
+
+ stats.getUidStats(uidStats, APP_UID2,
+ states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(0);
+ }
+
+ @Test
+ public void energyConsumerModel() {
+ TestBinaryStatePowerStatsProcessor processor = new TestBinaryStatePowerStatsProcessor(
+ POWER_COMPONENT, /* averagePowerMilliAmp */ 100, mUidResolver);
+
+ BinaryStatePowerStatsLayout statsLayout = new BinaryStatePowerStatsLayout();
+ PersistableBundle extras = new PersistableBundle();
+ statsLayout.toExtras(extras);
+ PowerStats.Descriptor descriptor = new PowerStats.Descriptor(POWER_COMPONENT,
+ statsLayout.getDeviceStatsArrayLength(), null, 0,
+ statsLayout.getUidStatsArrayLength(), extras);
+ PowerStats powerStats = new PowerStats(descriptor);
+ powerStats.stats = new long[descriptor.statsArrayLength];
+
+ PowerComponentAggregatedPowerStats stats = createAggregatedPowerStats(processor);
+
+ // Establish a baseline
+ processor.addPowerStats(stats, powerStats, mMonotonicClock.monotonicTime());
+
+ processor.noteStateChange(stats, buildHistoryItem(0, true, APP_UID1));
+
+ // Turn the screen off after 2.5 seconds
+ stats.setState(STATE_SCREEN, SCREEN_STATE_OTHER, 2500);
+ stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_BACKGROUND, 2500);
+ stats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND_SERVICE, 5000);
+
+ processor.noteStateChange(stats, buildHistoryItem(6000, false, APP_UID1));
+
+ statsLayout.setConsumedEnergy(powerStats.stats, 0, 2_160_000);
+ processor.addPowerStats(stats, powerStats, mMonotonicClock.monotonicTime());
+
+ processor.noteStateChange(stats, buildHistoryItem(7000, true, APP_UID2));
+
+ mClock.realtime = 11000;
+ statsLayout.setConsumedEnergy(powerStats.stats, 0, 1_440_000);
+ processor.addPowerStats(stats, powerStats, mMonotonicClock.monotonicTime());
+
+ processor.finish(stats, 11000);
+
+ // Total estimated power = 3,600,000 uC = 1.0 mAh
+ // of which 3,000,000 is distributed:
+ // Screen-on - 2500/6000 * 2160000 = 900000 uC = 0.25 mAh
+ // Screen-off - 3500/6000 * 2160000 = 1260000 uC = 0.35 mAh
+ // and 600,000 was fully with screen off:
+ // Screen-off - 1440000 uC = 0.4 mAh
+ long[] deviceStats = new long[descriptor.statsArrayLength];
+ stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_ON));
+ assertThat(statsLayout.getDevicePowerEstimate(deviceStats))
+ .isWithin(PRECISION).of(0.25);
+
+ stats.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_OTHER));
+ assertThat(statsLayout.getDevicePowerEstimate(deviceStats))
+ .isWithin(PRECISION).of(0.35 + 0.4);
+
+ // UID1 =
+ // 2,160,000 uC = 0.6 mAh
+ // split between three different states
+ // fg screen-on: 2500/6000
+ // bg screen-off: 2500/6000
+ // fgs screen-off: 1000/6000
+ double expectedPower1 = 0.6;
+ long[] uidStats = new long[descriptor.uidStatsArrayLength];
+ stats.getUidStats(uidStats, APP_UID1,
+ states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_FOREGROUND));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000);
+
+ stats.getUidStats(uidStats, APP_UID1,
+ states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_BACKGROUND));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower1 * 2500 / 6000);
+
+ stats.getUidStats(uidStats, APP_UID1,
+ states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_FOREGROUND_SERVICE));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower1 * 1000 / 6000);
+
+ // UID2 =
+ // 1440000 mA-ms = 0.4 mAh
+ // all in the same state
+ double expectedPower2 = 0.4;
+ stats.getUidStats(uidStats, APP_UID2,
+ states(POWER_STATE_OTHER, SCREEN_STATE_OTHER, PROCESS_STATE_CACHED));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(expectedPower2);
+
+ stats.getUidStats(uidStats, APP_UID2,
+ states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED));
+ assertThat(statsLayout.getUidPowerEstimate(uidStats))
+ .isWithin(PRECISION).of(0);
+ }
+
+
+ @NonNull
+ private BatteryStats.HistoryItem buildHistoryItem(int elapsedRealtime, boolean stateOn,
+ int uid) {
+ mClock.realtime = elapsedRealtime;
+ BatteryStats.HistoryItem historyItem = new BatteryStats.HistoryItem();
+ historyItem.time = mMonotonicClock.monotonicTime();
+ historyItem.states = stateOn ? TEST_STATE_FLAG : 0;
+ if (stateOn) {
+ historyItem.eventCode = BatteryStats.HistoryItem.EVENT_STATE_CHANGE
+ | BatteryStats.HistoryItem.EVENT_FLAG_START;
+ } else {
+ historyItem.eventCode = BatteryStats.HistoryItem.EVENT_STATE_CHANGE
+ | BatteryStats.HistoryItem.EVENT_FLAG_FINISH;
+ }
+ historyItem.eventTag = historyItem.localEventTag;
+ historyItem.eventTag.uid = uid;
+ historyItem.eventTag.string = "test";
+ return historyItem;
+ }
+
+ private int[] states(int... states) {
+ return states;
+ }
+
+ private static PowerComponentAggregatedPowerStats createAggregatedPowerStats(
+ BinaryStatePowerStatsProcessor processor) {
+ AggregatedPowerStatsConfig config = new AggregatedPowerStatsConfig();
+ config.trackPowerComponent(POWER_COMPONENT)
+ .trackDeviceStates(STATE_POWER, STATE_SCREEN)
+ .trackUidStates(STATE_POWER, STATE_SCREEN, STATE_PROCESS_STATE)
+ .setProcessor(processor);
+
+ AggregatedPowerStats aggregatedPowerStats = new AggregatedPowerStats(config);
+ PowerComponentAggregatedPowerStats powerComponentStats =
+ aggregatedPowerStats.getPowerComponentStats(POWER_COMPONENT);
+ processor.start(powerComponentStats, 0);
+
+ powerComponentStats.setState(STATE_POWER, POWER_STATE_OTHER, 0);
+ powerComponentStats.setState(STATE_SCREEN, SCREEN_STATE_ON, 0);
+ powerComponentStats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND, 0);
+ powerComponentStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0);
+
+ return powerComponentStats;
+ }
+}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsProcessorTest.java
index 752bc27..c88f0a9 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsProcessorTest.java
@@ -200,7 +200,7 @@
aggregatedStats.addPowerStats(collector.collectStats(), 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
BluetoothPowerStatsLayout statsLayout =
new BluetoothPowerStatsLayout(aggregatedStats.getPowerStatsDescriptor());
@@ -301,7 +301,7 @@
aggregatedStats.addPowerStats(collector.collectStats(), 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
BluetoothPowerStatsLayout statsLayout =
new BluetoothPowerStatsLayout(aggregatedStats.getPowerStatsDescriptor());
@@ -408,7 +408,7 @@
aggregatedStats.addPowerStats(collector.collectStats(), 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
BluetoothPowerStatsLayout statsLayout =
new BluetoothPowerStatsLayout(aggregatedStats.getPowerStatsDescriptor());
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsProcessorTest.java
index 6b5da81..b6b759e 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsProcessorTest.java
@@ -128,7 +128,7 @@
states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED),
values(1500, 2000, 1000), 1.252578);
- mProcessor.finish(mStats);
+ mProcessor.finish(mStats, 10_000);
mStats.verifyPowerEstimates();
}
@@ -173,7 +173,7 @@
states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED),
values(1500, 2000, 1000), 0.80773);
- mProcessor.finish(mStats);
+ mProcessor.finish(mStats, 10_000);
mStats.verifyPowerEstimates();
}
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 29ef3b6..137c2a6 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
@@ -228,7 +228,7 @@
aggregatedStats.addPowerStats(powerStats, 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
MobileRadioPowerStatsLayout statsLayout =
new MobileRadioPowerStatsLayout(
@@ -475,7 +475,7 @@
aggregatedStats.addPowerStats(powerStats, 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
return aggregatedStats;
}
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 69d655b..548d54c 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
@@ -203,11 +203,11 @@
aggregatedPowerStats.addPowerStats(collector.collectStats(), 10_000);
- mobileStatsProcessor.finish(mobileRadioStats);
+ mobileStatsProcessor.finish(mobileRadioStats, 10_000);
PowerComponentAggregatedPowerStats stats =
aggregatedPowerStats.getPowerComponentStats(BatteryConsumer.POWER_COMPONENT_PHONE);
- phoneStatsProcessor.finish(stats);
+ phoneStatsProcessor.finish(stats, 10_000);
PowerStatsLayout statsLayout =
new PowerStatsLayout(stats.getPowerStatsDescriptor());
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 3ceaf35..ff56691 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
@@ -234,7 +234,7 @@
aggregatedStats.addPowerStats(collector.collectStats(), 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
WifiPowerStatsLayout statsLayout =
new WifiPowerStatsLayout(aggregatedStats.getPowerStatsDescriptor());
@@ -355,7 +355,7 @@
aggregatedStats.addPowerStats(collector.collectStats(), 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
WifiPowerStatsLayout statsLayout =
new WifiPowerStatsLayout(aggregatedStats.getPowerStatsDescriptor());
@@ -454,7 +454,7 @@
aggregatedStats.addPowerStats(collector.collectStats(), 10_000);
- processor.finish(aggregatedStats);
+ processor.finish(aggregatedStats, 10_000);
WifiPowerStatsLayout statsLayout =
new WifiPowerStatsLayout(aggregatedStats.getPowerStatsDescriptor());
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index c80e8eb..e72d9e7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -5590,6 +5590,12 @@
mContext.binder.callingUid = managedProfileAdminUid;
addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R);
+ // Profile has a unified challenge
+ doReturn(false).when(getServices().lockPatternUtils)
+ .isSeparateProfileChallengeEnabled(managedProfileUserId);
+ doReturn(true).when(getServices().lockPatternUtils)
+ .isProfileWithUnifiedChallenge(managedProfileUserId);
+
dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH);
parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
@@ -5610,6 +5616,12 @@
mContext.binder.callingUid = managedProfileAdminUid;
addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R);
+ // Profile has a unified challenge
+ doReturn(false).when(getServices().lockPatternUtils)
+ .isSeparateProfileChallengeEnabled(managedProfileUserId);
+ doReturn(true).when(getServices().lockPatternUtils)
+ .isProfileWithUnifiedChallenge(managedProfileUserId);
+
dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
dpm.setPasswordMinimumLength(admin1, 8);
dpm.setPasswordMinimumLetters(admin1, 1);
@@ -5870,6 +5882,8 @@
.thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
doReturn(separateChallenge).when(getServices().lockPatternUtils)
.isSeparateProfileChallengeEnabled(userId);
+ doReturn(!separateChallenge).when(getServices().lockPatternUtils)
+ .isProfileWithUnifiedChallenge(userId);
when(getServices().userManager.getCredentialOwnerProfile(userId))
.thenReturn(separateChallenge ? userId : UserHandle.USER_SYSTEM);
when(getServices().lockSettingsInternal.getUserPasswordMetrics(userId))
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index abd3abe..e64397d 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -372,8 +372,8 @@
doReturn(true)
.when(mWindowManagerInternal)
.setContentRecordingSession(any(ContentRecordingSession.class));
- ContentRecordingSession taskSession =
- createTaskSession(mock(IBinder.class), targetUid);
+ ContentRecordingSession taskSession = createTaskSession(mock(IBinder.class));
+ taskSession.setTargetUid(targetUid);
service.setContentRecordingSession(taskSession);
projection.stop();
@@ -708,8 +708,8 @@
mService =
new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
- ContentRecordingSession taskSession =
- createTaskSession(mock(IBinder.class), targetUid);
+ ContentRecordingSession taskSession = createTaskSession(mock(IBinder.class));
+ taskSession.setTargetUid(targetUid);
mService.setContentRecordingSession(taskSession);
MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
@@ -915,8 +915,8 @@
.setContentRecordingSession(any(ContentRecordingSession.class));
int targetUid = 123455;
- ContentRecordingSession taskSession =
- createTaskSession(mock(IBinder.class), targetUid);
+ ContentRecordingSession taskSession = createTaskSession(mock(IBinder.class));
+ taskSession.setTargetUid(targetUid);
service.setContentRecordingSession(taskSession);
verify(mMediaProjectionMetricsLogger).logInProgress(projection.uid, targetUid);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java
index d04c518..f6e1162 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java
@@ -16,6 +16,10 @@
package com.android.server.notification;
+import static android.service.notification.Condition.SOURCE_USER_ACTION;
+import static android.service.notification.Condition.STATE_FALSE;
+import static android.service.notification.Condition.STATE_TRUE;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
@@ -27,16 +31,20 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.app.Flags;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.content.pm.IPackageManager;
import android.net.Uri;
import android.os.IInterface;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.Condition;
import com.android.server.UiServiceTestCase;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -52,6 +60,10 @@
@Mock
private ConditionProviders.Callback mCallback;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(
+ SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -67,8 +79,8 @@
ManagedServices.ManagedServiceInfo msi = mProviders.new ManagedServiceInfo(
mock(IInterface.class), cn, 0, false, mock(ServiceConnection.class), 33, 100);
Condition[] conditions = new Condition[] {
- new Condition(Uri.parse("a"), "summary", Condition.STATE_TRUE),
- new Condition(Uri.parse("b"), "summary2", Condition.STATE_TRUE)
+ new Condition(Uri.parse("a"), "summary", STATE_TRUE),
+ new Condition(Uri.parse("b"), "summary2", STATE_TRUE)
};
mProviders.notifyConditions("package", msi, conditions);
@@ -85,9 +97,9 @@
mock(IInterface.class), new ComponentName("package", "cls"), 0, false,
mock(ServiceConnection.class), 33, 100);
Condition[] conditionsToNotify = new Condition[] {
- new Condition(Uri.parse("a"), "summary", Condition.STATE_TRUE),
- new Condition(Uri.parse("b"), "summary2", Condition.STATE_TRUE),
- new Condition(Uri.parse("c"), "summary3", Condition.STATE_TRUE)
+ new Condition(Uri.parse("a"), "summary", STATE_TRUE),
+ new Condition(Uri.parse("b"), "summary2", STATE_TRUE),
+ new Condition(Uri.parse("c"), "summary3", STATE_TRUE)
};
mProviders.notifyConditions("package", msi, conditionsToNotify);
@@ -104,10 +116,10 @@
mock(IInterface.class), new ComponentName("package", "cls"), 0, false,
mock(ServiceConnection.class), 33, 100);
Condition[] conditionsToNotify = new Condition[] {
- new Condition(Uri.parse("a"), "summary", Condition.STATE_TRUE),
- new Condition(Uri.parse("b"), "summary2", Condition.STATE_TRUE),
- new Condition(Uri.parse("a"), "summary3", Condition.STATE_FALSE),
- new Condition(Uri.parse("a"), "summary4", Condition.STATE_FALSE)
+ new Condition(Uri.parse("a"), "summary", STATE_TRUE),
+ new Condition(Uri.parse("b"), "summary2", STATE_TRUE),
+ new Condition(Uri.parse("a"), "summary3", STATE_FALSE),
+ new Condition(Uri.parse("a"), "summary4", STATE_FALSE)
};
mProviders.notifyConditions("package", msi, conditionsToNotify);
@@ -124,10 +136,10 @@
mock(IInterface.class), new ComponentName("package", "cls"), 0, false,
mock(ServiceConnection.class), 33, 100);
Condition[] conditionsToNotify = new Condition[] {
- new Condition(Uri.parse("a"), "summary", Condition.STATE_TRUE),
+ new Condition(Uri.parse("a"), "summary", STATE_TRUE),
null,
null,
- new Condition(Uri.parse("b"), "summary", Condition.STATE_TRUE)
+ new Condition(Uri.parse("b"), "summary", STATE_TRUE)
};
mProviders.notifyConditions("package", msi, conditionsToNotify);
@@ -138,6 +150,57 @@
}
@Test
+ @EnableFlags(Flags.FLAG_MODES_UI)
+ public void notifyConditions_appCannotUndoUserEnablement() {
+ ManagedServices.ManagedServiceInfo msi = mProviders.new ManagedServiceInfo(
+ mock(IInterface.class), new ComponentName("package", "cls"), 0, false,
+ mock(ServiceConnection.class), 33, 100);
+ // First, user enabled mode
+ Condition[] userConditions = new Condition[] {
+ new Condition(Uri.parse("a"), "summary", STATE_TRUE, SOURCE_USER_ACTION)
+ };
+ mProviders.notifyConditions("package", msi, userConditions);
+ verify(mCallback).onConditionChanged(eq(Uri.parse("a")), eq(userConditions[0]));
+
+ // Second, app tries to disable it, but cannot
+ Condition[] appConditions = new Condition[] {
+ new Condition(Uri.parse("a"), "summary", STATE_FALSE)
+ };
+ mProviders.notifyConditions("package", msi, appConditions);
+ verify(mCallback).onConditionChanged(eq(Uri.parse("a")), eq(userConditions[0]));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_MODES_UI)
+ public void notifyConditions_appCanTakeoverUserEnablement() {
+ ManagedServices.ManagedServiceInfo msi = mProviders.new ManagedServiceInfo(
+ mock(IInterface.class), new ComponentName("package", "cls"), 0, false,
+ mock(ServiceConnection.class), 33, 100);
+ // First, user enabled mode
+ Condition[] userConditions = new Condition[] {
+ new Condition(Uri.parse("a"), "summary", STATE_TRUE, SOURCE_USER_ACTION)
+ };
+ mProviders.notifyConditions("package", msi, userConditions);
+ verify(mCallback).onConditionChanged(eq(Uri.parse("a")), eq(userConditions[0]));
+
+ // Second, app now thinks the rule should be on due it its intelligence
+ Condition[] appConditions = new Condition[] {
+ new Condition(Uri.parse("a"), "summary", STATE_TRUE)
+ };
+ mProviders.notifyConditions("package", msi, appConditions);
+ verify(mCallback).onConditionChanged(eq(Uri.parse("a")), eq(appConditions[0]));
+
+ // Lastly, app can turn rule off when its intelligence think it should be off
+ appConditions = new Condition[] {
+ new Condition(Uri.parse("a"), "summary", STATE_FALSE)
+ };
+ mProviders.notifyConditions("package", msi, appConditions);
+ verify(mCallback).onConditionChanged(eq(Uri.parse("a")), eq(appConditions[0]));
+
+ verifyNoMoreInteractions(mCallback);
+ }
+
+ @Test
public void testRemoveDefaultFromConfig() {
final int userId = 0;
ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1");
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index e564ba6..15c9bfb 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -10696,6 +10696,7 @@
}
@Test
+ @DisableFlags(android.app.Flags.FLAG_REMOVE_REMOTE_VIEWS)
public void testRemoveLargeRemoteViews() throws Exception {
int removeSize = mContext.getResources().getInteger(
com.android.internal.R.integer.config_notificationStripRemoteViewSizeBytes);
@@ -10758,6 +10759,46 @@
}
@Test
+ @EnableFlags(android.app.Flags.FLAG_REMOVE_REMOTE_VIEWS)
+ public void testRemoveRemoteViews() throws Exception {
+ Notification np = new Notification.Builder(mContext, "test")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setContentText("test")
+ .setCustomContentView(mock(RemoteViews.class))
+ .setCustomBigContentView(mock(RemoteViews.class))
+ .setCustomHeadsUpContentView(mock(RemoteViews.class))
+ .build();
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setContentText("test")
+ .setCustomContentView(mock(RemoteViews.class))
+ .setCustomBigContentView(mock(RemoteViews.class))
+ .setCustomHeadsUpContentView(mock(RemoteViews.class))
+ .setPublicVersion(np)
+ .build();
+
+ assertNotNull(n.contentView);
+ assertNotNull(n.bigContentView);
+ assertNotNull(n.headsUpContentView);
+
+ assertTrue(np.extras.containsKey(Notification.EXTRA_CONTAINS_CUSTOM_VIEW));
+ assertNotNull(np.contentView);
+ assertNotNull(np.bigContentView);
+ assertNotNull(np.headsUpContentView);
+
+ mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+
+ assertNull(n.contentView);
+ assertNull(n.bigContentView);
+ assertNull(n.headsUpContentView);
+ assertNull(n.publicVersion.contentView);
+ assertNull(n.publicVersion.bigContentView);
+ assertNull(n.publicVersion.headsUpContentView);
+
+ verify(mUsageStats, times(1)).registerImageRemoved(mPkg);
+ }
+
+ @Test
public void testNotificationBubbles_flagAutoExpandForeground_fails_notForeground()
throws Exception {
setUpPrefsForBubbles(mPkg, mUid,
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 fd69217..2e571bb 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -20,7 +20,7 @@
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ALL_APPS;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ASSIST;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_NOTIFICATION_PANEL;
-import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL;
+import static com.android.server.policy.PhoneWindowManager.SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -288,12 +288,12 @@
}
@Keep
- private static Object[][] shortPressOnSettingsTestArguments() {
- // testName, testKeys, shortPressOnSettingsBehavior, expectedLogEvent, expectedKey,
+ private static Object[][] settingsKeyTestArguments() {
+ // testName, testKeys, settingsKeyBehavior, expectedLogEvent, expectedKey,
// expectedModifierState
return new Object[][]{
{"SETTINGS key -> Toggle Notification panel", new int[]{KeyEvent.KEYCODE_SETTINGS},
- SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL,
+ SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL,
KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL, KeyEvent.KEYCODE_SETTINGS, 0}};
}
@@ -303,7 +303,7 @@
mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID, DEVICE_BUS);
mPhoneWindowManager.overrideLaunchHome();
mPhoneWindowManager.overrideSearchKeyBehavior(
- PhoneWindowManager.SEARCH_BEHAVIOR_TARGET_ACTIVITY);
+ PhoneWindowManager.SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY);
mPhoneWindowManager.overrideEnableBugReportTrigger(true);
mPhoneWindowManager.overrideStatusBarManagerInternal();
mPhoneWindowManager.overrideStartActivity();
@@ -349,11 +349,11 @@
}
@Test
- @Parameters(method = "shortPressOnSettingsTestArguments")
- public void testShortPressOnSettings(String testName, int[] testKeys,
- int shortPressOnSettingsBehavior, KeyboardLogEvent expectedLogEvent, int expectedKey,
+ @Parameters(method = "settingsKeyTestArguments")
+ public void testSettingsKey(String testName, int[] testKeys,
+ int settingsKeyBehavior, KeyboardLogEvent expectedLogEvent, int expectedKey,
int expectedModifierState) {
- mPhoneWindowManager.overrideShortPressOnSettingsBehavior(shortPressOnSettingsBehavior);
+ mPhoneWindowManager.overrideSettingsKeyBehavior(settingsKeyBehavior);
sendKeyCombination(testKeys, 0 /* duration */);
mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
expectedKey, expectedModifierState, DEVICE_BUS,
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index dd9d05a..fdb57d1 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -496,8 +496,8 @@
mPhoneWindowManager.mDoubleTapOnHomeBehavior = behavior;
}
- void overrideShortPressOnSettingsBehavior(int behavior) {
- mPhoneWindowManager.mShortPressOnSettingsBehavior = behavior;
+ void overrideSettingsKeyBehavior(int behavior) {
+ mPhoneWindowManager.mSettingsKeyBehavior = behavior;
}
void overrideCanStartDreaming(boolean canDream) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
index 12c1377..a4bec64 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
@@ -57,7 +57,8 @@
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class DesktopModeLaunchParamsModifierTests extends LaunchParamsModifierTestsBase {
+public class DesktopModeLaunchParamsModifierTests extends
+ LaunchParamsModifierTestsBase<DesktopModeLaunchParamsModifier> {
@Before
public void setUp() throws Exception {
mActivity = new ActivityBuilder(mAtm).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsModifierTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsModifierTestsBase.java
index 55f5df1..87671f2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsModifierTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsModifierTestsBase.java
@@ -33,7 +33,7 @@
import com.android.server.wm.LaunchParamsController.LaunchParamsModifier;
/** Common base class for launch param modifier unit test classes. */
-public class LaunchParamsModifierTestsBase extends WindowTestsBase{
+public class LaunchParamsModifierTestsBase<T extends LaunchParamsModifier> extends WindowTestsBase {
static final Rect DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0,
/* right */ 1920, /* bottom */ 1080);
@@ -42,7 +42,7 @@
ActivityRecord mActivity;
- LaunchParamsModifier mTarget;
+ T mTarget;
LaunchParams mCurrent;
LaunchParams mResult;
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 6b605ec..96ddfe8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -108,6 +108,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.view.InsetsFrameProvider;
@@ -188,6 +189,7 @@
private void setUpApp(DisplayContent display) {
mTask = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true).build();
mActivity = mTask.getTopNonFinishingActivity();
+ doReturn(false).when(mActivity).isImmersiveMode(any());
}
private void setUpDisplaySizeWithApp(int dw, int dh) {
@@ -396,6 +398,55 @@
verify(translucentActivity.mLetterboxUiController).updateInheritedLetterbox();
}
+ // TODO(b/333663877): Enable test after fix
+ @Test
+ @RequiresFlagsDisabled({Flags.FLAG_INSETS_DECOUPLED_CONFIGURATION})
+ public void testRepositionLandscapeImmersiveAppWithDisplayCutout() {
+ final int dw = 2100;
+ final int dh = 2000;
+ final int cutoutHeight = 150;
+ final TestDisplayContent display = new TestDisplayContent.Builder(mAtm, dw, dh)
+ .setCanRotate(false)
+ .setNotch(cutoutHeight)
+ .build();
+ setUpApp(display);
+ display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mWm.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f);
+ mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+
+ doReturn(true).when(mActivity).isImmersiveMode(any());
+ prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
+ SCREEN_ORIENTATION_LANDSCAPE);
+ addWindowToActivity(mActivity);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+
+ final Function<ActivityRecord, Rect> innerBoundsOf =
+ (ActivityRecord a) -> {
+ final Rect bounds = new Rect();
+ a.mLetterboxUiController.getLetterboxInnerBounds(bounds);
+ return bounds;
+ };
+
+ final Consumer<Integer> doubleClick =
+ (Integer y) -> {
+ mActivity.mLetterboxUiController.handleVerticalDoubleTap(y);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+ };
+
+ final Rect bounds = mActivity.getBounds();
+ assertTrue(bounds.top > cutoutHeight && bounds.bottom < dh);
+ assertEquals(dw, bounds.width());
+
+ // Double click bottom.
+ doubleClick.accept(dh - 10);
+ assertEquals(dh, innerBoundsOf.apply(mActivity).bottom);
+
+ // Double click top.
+ doubleClick.accept(10);
+ doubleClick.accept(10);
+ assertEquals(cutoutHeight, innerBoundsOf.apply(mActivity).top);
+ }
+
@Test
public void testResetOpaqueReferenceWhenOpaqueIsDestroyed() {
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
@@ -4034,8 +4085,7 @@
// Prepare unresizable landscape activity
prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
- final DisplayPolicy displayPolicy = mActivity.mDisplayContent.getDisplayPolicy();
- doReturn(immersive).when(displayPolicy).isImmersiveMode();
+ doReturn(immersive).when(mActivity).isImmersiveMode(any());
mActivity.mRootWindowContainer.performSurfacePlacement();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 2ce21ba..3c921c6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -70,7 +70,8 @@
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class TaskLaunchParamsModifierTests extends LaunchParamsModifierTestsBase {
+public class TaskLaunchParamsModifierTests extends
+ LaunchParamsModifierTestsBase<TaskLaunchParamsModifier> {
private static final Rect SMALL_DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0,
/* right */ 1000, /* bottom */ 500);
private static final Rect SMALL_DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100,
@@ -1898,8 +1899,7 @@
}
Rect startingBounds = new Rect(0, 0, 20, 20);
Rect adjustedBounds = new Rect(startingBounds);
- ((TaskLaunchParamsModifier) mTarget).adjustBoundsToAvoidConflict(displayBounds,
- existingTaskBounds, adjustedBounds);
+ mTarget.adjustBoundsToAvoidConflict(displayBounds, existingTaskBounds, adjustedBounds);
assertEquals(startingBounds, adjustedBounds);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 80c066d..698afaa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -1549,8 +1549,10 @@
});
assertTrue(activity1.isVisible());
doReturn(false).when(task1).isTranslucent(null);
+ doReturn(false).when(task1).isTranslucentForTransition();
assertTrue(controller.canApplyDim(task1));
doReturn(true).when(task1).isTranslucent(null);
+ doReturn(true).when(task1).isTranslucentForTransition();
assertFalse(controller.canApplyDim(task1));
controller.finishTransition(closeTransition);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 7e6301f..24ebad6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -795,39 +795,55 @@
}
@Test
- public void testGetTaskWindowContainerTokenForLaunchCookie_nullCookie() {
- WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForLaunchCookie(null);
- assertThat(wci).isNull();
- }
-
- @Test
- public void testGetTaskWindowContainerTokenForLaunchCookie_invalidCookie() {
+ public void testGetTaskWindowContainerTokenForRecordingSession_invalidCookie() {
Binder cookie = new Binder("test cookie");
- WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForLaunchCookie(cookie);
+ WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForRecordingSession(
+ ContentRecordingSession.createTaskSession(cookie));
assertThat(wci).isNull();
final ActivityRecord testActivity = new ActivityBuilder(mAtm)
.setCreateTask(true)
.build();
- wci = mWm.getTaskWindowContainerInfoForLaunchCookie(cookie);
+ wci = mWm.getTaskWindowContainerInfoForRecordingSession(
+ ContentRecordingSession.createTaskSession(cookie));
assertThat(wci).isNull();
}
@Test
- public void testGetTaskWindowContainerTokenForLaunchCookie_validCookie() {
+ public void testGetTaskWindowContainerTokenForRecordingSession_validCookie() {
final Binder cookie = new Binder("ginger cookie");
final WindowContainerToken launchRootTask = mock(WindowContainerToken.class);
final int uid = 123;
setupActivityWithLaunchCookie(cookie, launchRootTask, uid);
- WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForLaunchCookie(cookie);
+ WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForRecordingSession(
+ ContentRecordingSession.createTaskSession(cookie));
mExpect.that(wci.getToken()).isEqualTo(launchRootTask);
mExpect.that(wci.getUid()).isEqualTo(uid);
}
@Test
- public void testGetTaskWindowContainerTokenForLaunchCookie_multipleCookies() {
+ public void testGetTaskWindowContainerTokenForRecordingSession_validTaskId() {
+ final WindowContainerToken launchRootTask = mock(WindowContainerToken.class);
+ final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class);
+ when(remoteToken.toWindowContainerToken()).thenReturn(launchRootTask);
+
+ final int uid = 123;
+ final ActivityRecord testActivity =
+ new ActivityBuilder(mAtm).setCreateTask(true).setUid(uid).build();
+ testActivity.mLaunchCookie = null;
+ testActivity.getTask().mRemoteToken = remoteToken;
+
+ WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForRecordingSession(
+ ContentRecordingSession.createTaskSession(
+ new Binder("cookie"), testActivity.getTask().mTaskId));
+ mExpect.that(wci.getToken()).isEqualTo(launchRootTask);
+ mExpect.that(wci.getUid()).isEqualTo(uid);
+ }
+
+ @Test
+ public void testGetTaskWindowContainerTokenForRecordingSession_multipleCookies() {
final Binder cookie1 = new Binder("ginger cookie");
final WindowContainerToken launchRootTask1 = mock(WindowContainerToken.class);
final int uid1 = 123;
@@ -839,13 +855,14 @@
setupActivityWithLaunchCookie(new Binder("peanut butter cookie"),
mock(WindowContainerToken.class), /* uid= */ 789);
- WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForLaunchCookie(cookie1);
+ WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForRecordingSession(
+ ContentRecordingSession.createTaskSession(cookie1));
mExpect.that(wci.getToken()).isEqualTo(launchRootTask1);
mExpect.that(wci.getUid()).isEqualTo(uid1);
}
@Test
- public void testGetTaskWindowContainerTokenForLaunchCookie_multipleCookies_noneValid() {
+ public void testGetTaskWindowContainerTokenForRecordingSession_multipleCookies_noneValid() {
setupActivityWithLaunchCookie(new Binder("ginger cookie"),
mock(WindowContainerToken.class), /* uid= */ 123);
@@ -855,8 +872,8 @@
setupActivityWithLaunchCookie(new Binder("peanut butter cookie"),
mock(WindowContainerToken.class), /* uid= */ 789);
- WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForLaunchCookie(
- new Binder("some other cookie"));
+ WindowContainerInfo wci = mWm.getTaskWindowContainerInfoForRecordingSession(
+ ContentRecordingSession.createTaskSession(new Binder("some other cookie")));
assertThat(wci).isNull();
}
@@ -895,6 +912,7 @@
public void setContentRecordingSession_sessionContentTask_matchingTask_returnsTrue() {
WindowManagerInternal wmInternal = LocalServices.getService(WindowManagerInternal.class);
ActivityRecord activityRecord = createActivityRecord(createTask(mDefaultDisplay));
+ activityRecord.mLaunchCookie = new Binder();
ContentRecordingSession session = ContentRecordingSession.createTaskSession(
activityRecord.mLaunchCookie);
@@ -908,6 +926,7 @@
WindowManagerInternal wmInternal = LocalServices.getService(WindowManagerInternal.class);
Task task = createTask(mDefaultDisplay);
ActivityRecord activityRecord = createActivityRecord(task);
+ activityRecord.mLaunchCookie = new Binder();
ContentRecordingSession session =
ContentRecordingSession.createTaskSession(activityRecord.mLaunchCookie);
@@ -915,7 +934,7 @@
mExpect.that(session.getTokenToRecord())
.isEqualTo(task.mRemoteToken.toWindowContainerToken().asBinder());
- mExpect.that(session.getTargetUid()).isEqualTo(activityRecord.getUid());
+ mExpect.that(session.getTargetUid()).isEqualTo(task.effectiveUid);
}
@Test
diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
index 379b45c..a23f211 100644
--- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
+++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
@@ -24,6 +24,7 @@
import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.legacy.LegacyFlickerTestFactory
import android.tools.traces.parsers.toFlickerComponent
+import androidx.test.filters.FlakyTest
import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import com.android.server.wm.flicker.testapp.ActivityOptions
@@ -174,6 +175,12 @@
}
}
+ @FlakyTest(bugId = 342596801)
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ }
+
@Ignore("Not applicable to this CUJ.")
override fun visibleLayersShownMoreThanOneConsecutiveEntry() {}
diff --git a/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/OpenShowWhenLockedSeamlessAppRotationTest.kt b/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/OpenShowWhenLockedSeamlessAppRotationTest.kt
new file mode 100644
index 0000000..bf569bc
--- /dev/null
+++ b/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/OpenShowWhenLockedSeamlessAppRotationTest.kt
@@ -0,0 +1,125 @@
+/*
+ * 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.flicker.rotation
+
+import android.platform.test.annotations.Presubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.flicker.assertions.FlickerTest
+import android.tools.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.flicker.legacy.FlickerBuilder
+import android.tools.flicker.legacy.LegacyFlickerTest
+import android.tools.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.traces.component.ComponentNameMatcher
+import com.android.server.wm.flicker.BaseTest
+import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
+import org.junit.Assume
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test opening an app over lockscreen with rotation change using seamless rotations.
+ */
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenShowWhenLockedSeamlessAppRotationTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
+ val testApp = SeamlessRotationAppHelper(instrumentation)
+
+ override val transition: FlickerBuilder.() -> Unit
+ get() = {
+ setup {
+ device.sleep()
+ wmHelper.StateSyncBuilder().withoutTopVisibleAppWindows().waitForAndVerify()
+ device.wakeUp()
+ val originalRotation = device.displayRotation
+ ChangeDisplayOrientationRule.setRotation(Rotation.ROTATION_90)
+ Assume.assumeTrue("Assume that lockscreen uses fixed orientation",
+ originalRotation == device.displayRotation)
+ }
+ transitions {
+ // The activity is show-when-locked, so the requested orientation will be changed
+ // from NOSENSOR(keyguard) to UNSPECIFIED(activity). Then the fixed-user-rotation
+ // (by setRotation) will take effect to rotate the display.
+ testApp.launchViaIntent(wmHelper)
+ }
+ teardown { testApp.exit(wmHelper) }
+ }
+
+ @Presubmit
+ @Test
+ fun notContainsRotationAnimation() {
+ flicker.assertLayers {
+ // Verifies that com.android.wm.shell.transition.ScreenRotationAnimation is not used.
+ notContains(ComponentNameMatcher("", "Animation leash of screenshot rotation"))
+ }
+ }
+
+ // Ignore the assertions which are included in SeamlessAppRotationTest.
+ @Test
+ @Ignore("Uninterested")
+ override fun statusBarLayerPositionAtStartAndEnd() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun statusBarLayerIsVisibleAtStartAndEnd() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun statusBarWindowIsAlwaysVisible() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun navBarLayerPositionAtStartAndEnd() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun navBarLayerIsVisibleAtStartAndEnd() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun navBarWindowIsVisibleAtStartAndEnd() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun navBarWindowIsAlwaysVisible() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {}
+
+ @Test
+ @Ignore("Uninterested")
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {}
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ // The rotation will be controlled by the setup of test.
+ return LegacyFlickerTestFactory.nonRotationTests(
+ supportedRotations = listOf(Rotation.ROTATION_0),
+ supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+ )
+ }
+ }
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index 3e500d9..45260bd 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -74,6 +74,7 @@
android:taskAffinity="com.android.server.wm.flicker.testapp.SeamlessRotationActivity"
android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
+ android:showWhenLocked="true"
android:label="SeamlessActivity"
android:exported="true">
<intent-filter>
diff --git a/tests/InputScreenshotTest/robotests/Android.bp b/tests/InputScreenshotTest/robotests/Android.bp
index 384f58a..d63fd69 100644
--- a/tests/InputScreenshotTest/robotests/Android.bp
+++ b/tests/InputScreenshotTest/robotests/Android.bp
@@ -69,4 +69,6 @@
upstream: true,
java_resource_dirs: ["config"],
instrumentation_for: "InputRoboApp",
+
+ strict_mode: false,
}
diff --git a/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt b/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
index 4c1fa6e..4995eeb 100644
--- a/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
+++ b/tools/processors/intdef_mappings/src/android/processor/IntDefProcessor.kt
@@ -30,7 +30,7 @@
import javax.lang.model.element.AnnotationValue
import javax.lang.model.element.TypeElement
import javax.tools.Diagnostic.Kind
-import javax.tools.StandardLocation.CLASS_OUTPUT
+import javax.tools.StandardLocation.SOURCE_OUTPUT
import kotlin.collections.set
/**
@@ -126,7 +126,7 @@
@Throws(IOException::class)
private fun outputToFile(annotationTypeToIntDefMapping: Map<String, IntDefMapping>) {
val resource = processingEnv.filer.createResource(
- CLASS_OUTPUT, "com.android.winscope", outputName)
+ SOURCE_OUTPUT, "com.android.winscope", outputName)
val writer = resource.openWriter()
serializeTo(annotationTypeToIntDefMapping, writer)
writer.close()
diff --git a/tools/processors/intdef_mappings/test/android/processor/IntDefProcessorTest.kt b/tools/processors/intdef_mappings/test/android/processor/IntDefProcessorTest.kt
index c0c159c..d87b6df 100644
--- a/tools/processors/intdef_mappings/test/android/processor/IntDefProcessorTest.kt
+++ b/tools/processors/intdef_mappings/test/android/processor/IntDefProcessorTest.kt
@@ -24,7 +24,7 @@
import org.junit.Test
import java.io.StringWriter
import javax.tools.JavaFileObject
-import javax.tools.StandardLocation.CLASS_OUTPUT
+import javax.tools.StandardLocation.SOURCE_OUTPUT
/**
* Tests for [IntDefProcessor]
@@ -112,7 +112,7 @@
.compile(filesToCompile.toMutableList())
assertThat(compilation).succeeded()
- assertThat(compilation).generatedFile(CLASS_OUTPUT, "com.android.winscope",
+ assertThat(compilation).generatedFile(SOURCE_OUTPUT, "com.android.winscope",
"intDefMapping.json").contentsAsUtf8String().isEqualTo(expectedFile)
}